Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

YAMineSweeper

by giulienk (Curate)
on Jan 16, 2002 at 14:02 UTC ( [id://139163]=CUFP: print w/replies, xml ) Need Help??

I read On Interviewing Candidates and Games in Perl so i felt it would be interesting to try to code a simple MineSweeper.
#!/usr/bin/perl # Usage: ./mine.pl [dimension] + # # enter coordinates to check like "5 6" (y coordinate first) + # #if you want to place a flag where you think there is a mine use "x 3 +4" # use strict;
my $dimension = $ARGV[0] || 10; my ($count, %old, %mines); my $fill_char = '.'; my @row = map {$fill_char} 1..$dimension; my @matrix = map {[@row]} @row; my @control = ([-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1] ); sub print_matrix { my $i; unshift @_, [map {$_} 1..$dimension]; for (@_) { my @row = @$_; unshift @row, $i++ || ' '; for (@row) { printf("%2s ", $_) ; } print $/; } } sub initialize_fields { my $i; while ($i < $dimension) { my ($x, $y) = map {int rand $dimension} 1..2; my $mine = join ' ', $x, $y; $mines{$mine}++ || $i++; } } sub check_square { die "BOOOOMMMM!!!\n" if is_bomb( @_ ); cq( @_ ); } sub cq { my ($x, $y) = @_; return unless $matrix[$x][$y] eq $fill_char; my $value = value( @_ ); $matrix[$x][$y] = $value; unless ( $value ) { for ( @control ) { @_ = @$_; my @nc = ($x + $_[0], $y + $_[1]); next if out_of_range( @nc ); next if $matrix[ $nc[0] ][ $nc[1] ] ne $fill_char; cq( @nc ); } } $count++; } sub value { my ($x, $y) = @_; my $value; for ( @control ) { @_ = @$_; my @nc = ($x + $_[0], $y + $_[1]); next if out_of_range( @nc ); $value += is_bomb( @nc ); } return $value; } sub is_bomb { my $mine = join ' ', @_; return $mines{$mine} ? 1 : 0; } sub out_of_range { return grep { $_ < 0 or $_ >= $dimension } @_; } initialize_fields; while (1) { print_matrix(@matrix); print "YOU WON!!!\n" and exit if $count >= ($dimension ** 2 - $dim +ension); print "Insert (y, x) = "; $_ = <STDIN>; print $/; my ($command, $x, $y) = /^(x)?\s*(\d+)\D+(\d+)/i; $x--; $y--; print "x or y out of range!!!\n\n" and next if out_of_range($x, $y +); if ( $command ) { if ( $matrix[$x][$y] eq 'X' ) { my $mine = join ' ', $x, $y; $matrix[$x][$y] = $old{$mine}; } else { my $mine = join ' ', $x, $y; $old{$mine} = $matrix[$x][$y]; $matrix[$x][$y] = 'X'; } } else { check_square($x, $y); } }
Update: fixed exploitable bug.
Update (20020117): cuter command parsing.

$|=$_='1g2i1u1l2i4e2n0k',map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g

Replies are listed 'Best First'.
Re: YAMineSweeper
by Juerd (Abbot) on Jan 16, 2002 at 14:53 UTC
    Hi,

    I like the idea of a simple minesweeper, and tried to make one myself :)

    Mine doesn't check user input and doesn't auto-sweep, but it fits in 5 lines :)
    It tests if the user won, and if so, quits the game.

    map$f[rand 8][rand 8]=1,0..9;@u=map[(',')x8],1..8;for(;$i=-2;){print$ i+++2?$i:' '," @$_\n"for[0..7],@u;($x,$y,$f)=split' ',<>;$f?$u[$y][$x ]='F':$u[$y][$x]ne'F'&&$f[$y][$x]&&die||do{$m=' ';for$z(-1..1){$y+$z> -1&&$x+$_>-1&&$f[$y+$z][$x+$_]&&$m++for-1..1}$u[$y][$x]=$m};for$z(0.. 7){for$q(0..7){$_=$u[$z][$q],$i+=$f[$z][$q]?!/^F/:/F/}}$i<8&&die"\n"}


    Open (and unflag if flagged) using "x y" ("0 0"), flag with "x y 1" ("0 0 1").

    Update (200201161311+0100) Bugs fixed, better checking scan
    Update (200201191544+0100) A previous bugfix introduced 3 new ones, making the game a bit unpredictable ;) Fixed now.
    Update (200201200039+0100) I need more sleep. Okay, I believe it's really playable now (I actually tried it this time (kick me not))
    0 1 2 3 4 5 6 7 0 1 , 1 1 , , , 2 1 1 1 , , , 3 1 , , 1 , , , 4 , , , 2 1 , , , 5 , , , , , , , , 6 , , , , , 2 1 1 7 , , , , , 1 6 0 Died at mine.pl line 3, <> line 29.
    As you can see, I'm not very good at this game :)

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

Re: YAMineSweeper
by belg4mit (Prior) on Jan 16, 2002 at 14:11 UTC
    Come on! Cartesian is x,y :-P

    --
    perl -pe "s/\b;([st])/'\1/mg"

      That's true! I coded it with (x, y) but then i found myself always getting the wrong point checked cause i looked at y first!

      $|=$_='1g2i1u1l2i4e2n0k',map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://139163]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2024-03-19 06:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found