论坛首页 Web前端技术论坛

ajax 扫雷(dojo框架)

浏览 2923 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2007-04-20  
写了个ajax扫雷,需要源码的直接留言好了,多提宝贵意见啊:)
http://www.zhekouju.cn/cgi-bin/mine.cgi
#!/usr/bin/perl
use lib "../lib";
use Utility;
use IpUtility;
use constant TMPL_FILE => '../tmpl/mine.html';
use strict;
use CGI::Carp qw(fatalsToBrowser);
use CGI::Session;
use constant NUMBER_BY_PAGE => 10;
use Date::Calc;

&main;

#www.zhekouju.cn
#author:Jiang shenli
#e-mail:jiangshenli@hotmail.com

# 3-dimension-structure
#a->[x][y][0] indicates if the cell is mine:  0->no  1->yes
#a->[x][y][1] indicates if how many mines around
#a->[x][y][2] indicates if the display state of the cell: 0->not yet shown  1->shown 2->flaged

sub main() {
	eval {
		my $dbh     = db_connect();
		my $query   = new CGI;
		my $data    = format_to_hash($query);
		my $session = new CGI::Session();

		if ( defined( $data->{add_record} ) ) {
			my $s1 =
			  $dbh->prepare(
"insert into record (user_name,record_time,ip,hour,minute,second)values (?,now(),?,?,?,?)"
			  );
			$s1->execute( $data->{user_name},
				&getIpAddress( $ENV{'REMOTE_ADDR'} ),
				$data->{hour}, $data->{minute}, $data->{second} );
			print $query->redirect( $ENV{SCRIPT_NAME} );
			return;
		}
		elsif ( defined( $data->{submit_new_review} ) ) {
			my $sth_insert =
			  $dbh->prepare(
"insert into guest_review_board (content,user_name,record_time,board) values (?,?,now(),1)"
			  );
			$sth_insert->execute( $data->{content}, $data->{user_name} );
			print $query->redirect( $ENV{SCRIPT_NAME} );
			return;
		}

		#		handle right click event
		elsif ( defined( $data->{sent_right} ) ) {
			print $query->header( { -type => 'text/html;charset=utf-8' } );
			my ( $x, $y ) = split( ',', $data->{sent_right} );
			print '{';
			$data->{a} = $session->param('map');
			$data->{a}->[$x][$y][2] = 2 - $data->{a}->[$x][$y][2];
			print 'result:[' . $x . ',' . $y . ','
			  . $data->{a}->[$x][$y][2] . '],';
			print "nothing:'nothing'}";
			$session->param( 'map', $data->{a} );

			#			&nice_print($data);
			return;
		}

		#		handle left click event
		elsif ( defined( $data->{sent_left} ) ) {
			if ( defined( $session->param('if_start') )
				and ( $session->param('if_start') eq 'yes' ) )
			{

				#			hande the non-first click event
				$data->{a} = $session->param('map');
				my ( $x, $y ) = split( ',', $data->{sent_left} );
				$data->{result} = '{';
				if ( $data->{a}->[$x][$y][0] == 1 ) {
					$data->{result} = $data->{result} . "state:'failed',";
					$data->{result} =
					  $data->{result} . &get_leavings_for_failure($data);
					$data->{result} =
					  $data->{result} . 'wrongX:' . $x . ',wrongY:' . $y . ',';
				}
				else {
					$data->{result} = $data->{result} . &show( $data, $x, $y );
					if ( if_success($data) ) {
						$data->{result} = $data->{result} . "state:'win',";
						my @now = Date::Calc::Today_and_Now();
						my @t   =
						  Date::Calc::Delta_YMDHMS(
							@{ $session->param('time') }, @now );
						$data->{result} =
						  $data->{result} . 'hour:' . $t[3] . ',';
						$data->{result} =
						  $data->{result} . 'minute:' . $t[4] . ',';
						$data->{result} =
						  $data->{result} . 'second:' . $t[5] . ',';

						$data->{result} =
						  $data->{result} . &get_leavings($data);
					}
					else {
						$data->{result} = $data->{result} . "state:'continue',";
					}
				}
				$data->{result} = $data->{result} . "nothing:'nothing'}";
				$session->param( 'map', $data->{a} );
				print $query->header( { -type => 'text/html; charset=utf-8' } );
				print $data->{result};
				return;
			}
			else {

				#			hande the first click event
				my @now = Date::Calc::Today_and_Now();
				$session->param( 'time',     \@now );
				$session->param( 'if_start', 'yes' );
				my ( $x, $y ) = split( ',', $data->{sent_left} );
				$data->{result} = '{';
				$data->{a}      = $session->param('map');
				&init( $data, $x, $y );
				$data->{result} = $data->{result} . &show( $data, $x, $y );

				if ( if_success($data) ) {
					$data->{result} = $data->{result} . "state:'win',";
					my @now = Date::Calc::Today_and_Now();
					my @t   =
					  Date::Calc::Delta_YMDHMS( @{ $session->param('time') },
						@now );
					$data->{result} = $data->{result} . 'hour:' . $t[3] . ',';
					$data->{result} = $data->{result} . 'minute:' . $t[4] . ',';
					$data->{result} = $data->{result} . 'second:' . $t[5] . ',';
					$data->{result} = $data->{result} . &get_leavings($data);
				}
				else {
					$data->{result} = $data->{result} . "state:'continue',";
				}
				$data->{result} = $data->{result} . "nothing:'nothing'}";
				$session->param( 'map', $data->{a} );
				print $query->header( { -type => 'text/html; charset=utf-8' } );
				print $data->{result};
				return;
			}
		}

		#		initialization request
		&init_init($data);
		$session->param( 'if_start', 'no' );
		$session->param( 'map',      $data->{a} );

		my $sth_select_all =
		  $dbh->prepare(
"select count(*) as 'total_reviews'  from guest_review_board where del_flag=0"
		  );
		$sth_select_all->execute();
		my $total_reviews =
		  ( $sth_select_all->fetchrow_hashref()->{total_reviews} );
		$data->{total_pages} =
		  int( ( $total_reviews + NUMBER_BY_PAGE - 1 ) / NUMBER_BY_PAGE );
		$data->{page}      = 1 unless defined( $data->{page} );
		$data->{next_page} = $data->{page} + 1;
		$data->{next_page} = 0 if $data->{next_page} > $data->{total_pages};
		$data->{pre_page}  = $data->{page} - 1;
		$data->{pre_page}  = 0 if $data->{pre_page} < 1;

		my $sth_get_reviews =
		  $dbh->prepare(
"select content,record_time,user_name from guest_review_board where board=1 order by record_time desc limit "
			  . ( ( $data->{page} - 1 ) * 10 )
			  . ",10 " );
		$sth_get_reviews->execute();
		my @temp_reviews;
		while ( my $temp_review = $sth_get_reviews->fetchrow_hashref() ) {
			push @temp_reviews, $temp_review;
		}
		$data->{reviews} = \@temp_reviews;
		$data->{ip}      = $ENV{'REMOTE_ADDR'};
		$data->{ip}      = &getIpAddress( $ENV{'REMOTE_ADDR'} );

		my $sth_get_records= $dbh->prepare("select * from record order by hour,minute,second");
		$sth_get_records->execute();
		my @temp_records;
		while ( my $temp_record = $sth_get_records->fetchrow_hashref() ) {
			push@temp_records, $temp_record;
		}
		$data->{records} = \@temp_records;
		my $cookie = $query->cookie(
			-name  => $session->name,
			-value => $session->id
		);
		print $query->header(
			{ -cookie => $cookie, -type => 'text/html; charset=utf-8' } );
		print_page_without_header( TMPL_FILE, $data );
#	die Dumper($data);
	};

	die $@ if $@;
}

#test if you have won:
#the way is to test if all the non-mine cell is shown
sub if_success() {
	my $data = shift;
	for ( my $i = 1 ; $i <= $data->{height} ; $i++ ) {
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {
			if ( $data->{a}->[$i][$j][0] == 0 and $data->{a}->[$i][$j][2] != 1 )
			{
				return 0;
			}
		}
	}
	return 1;
}

#the initialization before your first click ,assume there are no mines
#there will be mines after your first click
#default: there are 10 X 10 cells and 10 mines,you can change it by import specific parameter of url
sub init_init() {
	my $data = shift;
	$data->{width} = 10 unless defined( $data->{width} ) and $data->{width} > 0;
	$data->{height} = 10
	  unless defined( $data->{height} )
	  and $data->{height} > 0;
	$data->{mine_number} = 20
	  unless defined( $data->{mine_number} )
	  and $data->{mine_number} > 0;
	$data->{mine_number} = int( $data->{height} * $data->{width} / 2 )
	  unless defined( $data->{mine_number} )
	  and $data->{mine_number} < $data->{height} * $data->{width}
	  and $data->{mine_number} > 0;

	for ( my $i = 0 ; $i <= $data->{height} + 1 ; $i++ ) {
		for ( my $j = 0 ; $j <= $data->{width} + 1 ; $j++ ) {
			$data->{a}->[$i][$j] = [ 0, 0, 0 ];
		}
	}
}

#if win,get the leavings mine
sub get_leavings() {
	my $data = shift;
	my $temp = 'leaving:[';
	for ( my $i = 1 ; $i <= $data->{height} ; $i++ ) {
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {

			#			if it is mine and has not been shown
			if ( $data->{a}->[$i][$j][0] == 1 and $data->{a}->[$i][$j][2] == 0 )
			{
				$data->{a}->[$i][$j][2] = 2;
				$temp = $temp . '[' . $i . ',' . $j . '],';
			}
		}
	}
	$temp =~ s/,$//;
	$temp = $temp . '],';
	return $temp || '';

}

#if fail,get the leavings mine and give the wrong flag information
sub get_leavings_for_failure() {
	my $data = shift;
	my $temp = 'leaving:[';
	for ( my $i = 1 ; $i <= $data->{height} ; $i++ ) {
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {

			#			if it is mine and has not been shown
			if ( $data->{a}->[$i][$j][0] == 1 ) {
				$temp = $temp . '[' . $i . ',' . $j . ',0],';   #1 -> it is mine
			}
			if ( $data->{a}->[$i][$j][0] == 0 && $data->{a}->[$i][$j][2] == 2 )
			{
				$temp =
				  $temp . '[' . $i . ',' . $j
				  . ',2],';    #2-> it is not mine but you thought it was
			}
		}
	}
	$temp =~ s/,$//;
	$temp = $temp . '],';
	return $temp || '';

}

#the initialization after your first click
sub init() {
	my $data  = shift;
	my $x     = shift;
	my $y     = shift;
	my $total = $data->{width} * $data->{height};

	my @array = ( 0 .. $total - 1 );
	( $array[ ( $x - 1 ) * $data->{width} + $y - 1 ], $array[ $total - 1 ] ) =
	  ( $array[ $total - 1 ], $array[ ( $x - 1 ) * $data->{width} + $y - 1 ] );
	my $current = $total - 1;
	for (
		my $i = $current - 1 ;
		$i >= $total - 1 - 1 - $data->{mine_number} + 1 ;
		$i--
	  )
	{
		my $r = int( rand($current) );
		( $array[$r], $array[$i] ) = ( $array[$i], $array[$r] );
		$current--;
	}

	for (
		my $j = $total - 1 - 1 - $data->{mine_number} + 1 ;
		$j <= $total - 1 - 1 ;
		$j++
	  )
	{
		$data->{a}->[ int( $array[$j] / $data->{width} ) + 1 ]
		  [ $array[$j] % $data->{width} + 1 ][0] = 1;
	}
	for ( my $i = 1 ; $i <= $data->{height} ; $i++ ) {
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {
			$data->{a}->[$i][$j][1] =
			  $data->{a}->[ $i - 1 ][ $j - 1 ][0] +
			  $data->{a}->[ $i - 1 ][$j][0] +
			  $data->{a}->[ $i - 1 ][ $j + 1 ][0] +
			  $data->{a}->[ $i + 1 ][ $j - 1 ][0] +
			  $data->{a}->[ $i + 1 ][$j][0] +
			  $data->{a}->[ $i + 1 ][ $j + 1 ][0] +
			  $data->{a}->[$i][ $j - 1 ][0] + $data->{a}->[$i][ $j + 1 ][0];
		}
	}

}

#change the mine map state from array to string(to be saved by session)
#discarded because perl can traslate a reference to a string automatically
#but it is useful if you want to use other language
#sub toString() {
##	open TTT,">string_print.txt";
##	select TTT;
#	my $data   = shift;
#	my $string = '';
#	for ( my $i = 1 ; $i <= $data->{height} ; $i++ ) {
#		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {
#			$string =
#			    $string . $i . ',' . $j . ','
#			  . $data->{a}->[$i][$j][0] . ','
#			  . $data->{a}->[$i][$j][1] . ','
#			  . $data->{a}->[$i][$j][2] . ';';
#		}
#	}
##	print $string;
##	select STDOUT;
##	close TTT;
#	return $string;
#}

#change the mine map state from string(get from session) to array
#discarded because perl can traslate a reference to a string automatically
#but it is useful if you want to use other language
#sub toArray() {
#	my $string = shift;
#	my $a      = [ [] ];
#	my @array1 = split( ';', $string );
#	for ( my $i = 0 ; $i < scalar(@array1) ; $i++ ) {
#		my @array2 = split( ',', $array1[$i] );
#		$a->[ $array2[0] ][ $array2[1] ] =
#		  [ $array2[2], $array2[3], $array2[4] ];
#	}
#	return $a;
#}

#print the state map,just for debug
sub nice_print() {
	open TTT, ">array_print.txt";
	select TTT;
	my $data = shift;
	print "\n";
	for ( my $i = 1 ; $i <= $data->{height} ; $i++ ) {
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {
			print $data->{a}->[$i][$j][0] . ' ';
		}
		print '         ';
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {
			print $data->{a}->[$i][$j][1] . ' ';
		}
		print '         ';
		for ( my $j = 1 ; $j <= $data->{width} ; $j++ ) {
			print $data->{a}->[$i][$j][2] . ' ';
		}
		print "\n";
	}
	select STDOUT;
	close TTT;
}

# handle the left click event
sub show() {
	my $data = shift;
	my $x    = shift;
	my $y    = shift;
	$data->{temp_result}    = 'result:[';
	$data->{a}->[$x][$y][2] = 1;
	$data->{temp_result}    =
	    $data->{temp_result} . '[' . $x . ',' . $y . ','
	  . $data->{a}->[$x][$y][1] . '],';
	if ( $data->{a}->[$x][$y][1] == 0 ) {
		_clear_more( $data, $x, $y );
	}
	$data->{temp_result} =~ s/,$//;
	$data->{temp_result} = $data->{temp_result} . '],';
	return $data->{temp_result} || '';
}

sub _clear_more() {
	my $data = shift;
	my $x    = shift;
	my $y    = shift;
	if (    $x - 1 >= 1
		and $y - 1 >= 1
		and $data->{a}->[ $x - 1 ][ $y - 1 ][2] == 0 )
	{
		$data->{a}->[ $x - 1 ][ $y - 1 ][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '['
		  . ( $x - 1 ) . ','
		  . ( $y - 1 ) . ','
		  . $data->{a}->[ $x - 1 ][ $y - 1 ][1] . '],';
		if ( $data->{a}->[ $x - 1 ][ $y - 1 ][1] == 0 ) {
			&_clear_more( $data, $x - 1, $y - 1 );
		}
	}
	if (    $x - 1 >= 1
		and $data->{a}->[ $x - 1 ][$y][2] == 0 )
	{
		$data->{a}->[ $x - 1 ][$y][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '['
		  . ( $x - 1 ) . ','
		  . $y . ','
		  . $data->{a}->[ $x - 1 ][$y][1] . '],';
		if ( $data->{a}->[ $x - 1 ][$y][1] == 0 ) {
			&_clear_more( $data, $x - 1, $y );
		}
	}
	if (    $x - 1 >= 1
		and $y + 1 <= $data->{width}
		and $data->{a}->[ $x - 1 ][ $y + 1 ][2] == 0 )
	{
		$data->{a}->[ $x - 1 ][ $y + 1 ][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '['
		  . ( $x - 1 ) . ','
		  . ( $y + 1 ) . ','
		  . $data->{a}->[ $x - 1 ][ $y + 1 ][1] . '],';
		if ( $data->{a}->[ $x - 1 ][ $y + 1 ][1] == 0 ) {
			&_clear_more( $data, $x - 1, $y + 1 );
		}
	}
	if (    $y - 1 >= 1
		and $data->{a}->[$x][ $y - 1 ][2] == 0 )
	{
		$data->{a}->[$x][ $y - 1 ][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '[' . $x . ','
		  . ( $y - 1 ) . ','
		  . $data->{a}->[$x][ $y - 1 ][1] . '],';
		if ( $data->{a}->[$x][ $y - 1 ][1] == 0 ) {
			&_clear_more( $data, $x, $y - 1 );
		}
	}
	if (    $y + 1 <= $data->{width}
		and $data->{a}->[$x][ $y + 1 ][2] == 0 )
	{
		$data->{a}->[$x][ $y + 1 ][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '[' . $x . ','
		  . ( $y + 1 ) . ','
		  . $data->{a}->[$x][ $y + 1 ][1] . '],';
		if ( $data->{a}->[$x][ $y + 1 ][1] == 0 ) {
			&_clear_more( $data, $x, $y + 1 );
		}
	}
	if (    $x + 1 <= $data->{height}
		and $y - 1 >= 1
		and $data->{a}->[ $x + 1 ][ $y - 1 ][2] == 0 )
	{
		$data->{a}->[ $x + 1 ][ $y - 1 ][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '['
		  . ( $x + 1 ) . ','
		  . ( $y - 1 ) . ','
		  . $data->{a}->[ $x + 1 ][ $y - 1 ][1] . '],';
		if ( $data->{a}->[ $x + 1 ][ $y - 1 ][1] == 0 ) {
			&_clear_more( $data, $x + 1, $y - 1 );
		}
	}
	if (    $x + 1 <= $data->{height}
		and $data->{a}->[ $x + 1 ][$y][2] == 0 )
	{
		$data->{a}->[ $x + 1 ][$y][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '['
		  . ( $x + 1 ) . ','
		  . $y . ','
		  . $data->{a}->[ $x + 1 ][$y][1] . '],';
		if ( $data->{a}->[ $x + 1 ][$y][1] == 0 ) {
			&_clear_more( $data, $x + 1, $y );
		}
	}
	if (    $x + 1 <= $data->{height}
		and $y + 1 <= $data->{width}
		and $data->{a}->[ $x + 1 ][ $y + 1 ][2] == 0 )
	{
		$data->{a}->[ $x + 1 ][ $y + 1 ][2] = 1;
		$data->{temp_result} =
		    $data->{temp_result} . '['
		  . ( $x + 1 ) . ','
		  . ( $y + 1 ) . ','
		  . $data->{a}->[ $x + 1 ][ $y + 1 ][1] . '],';
		if ( $data->{a}->[ $x + 1 ][ $y + 1 ][1] == 0 ) {
			&_clear_more( $data, $x + 1, $y + 1 );
		}
	}

}

   发表时间:2007-04-20  
我要源码。。谢谢了

我的邮箱是 lvzg_abc@163.com
0 请登录后投票
   发表时间:2007-04-20  
我要一个 xhm1986@163.com
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics