#!/usr/local/bin/perl # # $Id: spider.pl,v 4.9 2002/07/21 06:49:49 kono Exp $ package TempCardPile; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK ); require Exporter; require AutoLoader; @ISA = qw(Exporter AutoLoader CardPlay::CardPile); @EXPORT = qw( ); $VERSION = "0.2"; use Tk; use Carp; use CardPlay::Card; use CardPlay::CardPile; use CardPlay::CardBoard; sub new { my $type = shift; my $self = CardPlay::CardPile->new(@_); $self->{'-mergeable'}=1; $self->{'-splitable'}=1; # $self->{'-deltay'}=20; bless $self; } sub can_merge { my ($self,$cardpile) = @_; my ($card) = $cardpile->first(); my ($last) = $self->last(); return 0 if (!defined($card)); return $self->intelligent($cardpile) if ($self eq $cardpile->{'-prevSplit'}); return 1 if ($self->empty()); if ($last->{'-state'} eq 'hide') { return $self->intelligent($cardpile); } return 1 if ($card->{'-number'}==$last->{'-number'}-1) ; return $self->intelligent($cardpile); } sub intelligent { my ($self,$cardpile) = @_; # remember this is called from can_merge. # use do_merge for undo logging etc. my ($suit) = $cardpile->first()->{'-suit'}; my ($number) = $cardpile->first()->{'-number'}; my ($last); my ($i); my ($tempPile) = $self->{'-tempPiles'}; foreach $i ( @{$tempPile} ) { next if ($i eq $self); $last = $i->last(); next if (! defined($last)); next if ($last->{'-suit'} ne $suit); next if ($last->{'-number'} != $number+1); $i->do_merge($cardpile); return 2; } foreach $i ( @{$tempPile} ) { next if ($i eq $self); $last = $i->last(); next if (! defined($last)); next if ($last->{'-number'} != $number+1); $i->do_merge($cardpile); return 2; } foreach $i ( @{$tempPile} ) { next if ($i eq $self); $last = $i->last(); next if (defined($last)); $i->do_merge($cardpile); return 2; } return 0; } sub can_split { my ($self,$i) = @_; my (@contents) = @{$self->{'-contents'}}; return 0 if (!defined($contents[$i])); return 0 if ($contents[$i]->{'-state'} eq 'hide'); my $suit = $contents[$i]->{'-suit'}; my $number = $contents[$i]->{'-number'}; for(;$i<=$#contents;$i++) { return 0 if (!defined($contents[$i])); return 0 if ($contents[$i]->{'-suit'} ne $suit); return 0 if ($contents[$i]->{'-number'} != $number); $number--; } return 1; } package DealCardPile; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK ); require Exporter; require AutoLoader; @ISA = qw(Exporter AutoLoader CardPlay::CardPile); @EXPORT = qw( ); $VERSION = "0.2"; use Tk; use Carp; use CardPlay::Card; use CardPlay::CardPile; use CardPlay::CardBoard; sub new { my $type = shift; my $self = CardPlay::CardPile->new(@_); $self->{'-deltay'}=0; $self->bind('<1>' => sub {$self->deal()}); bless $self; $self; } sub deal { my $self = shift; my @cp= @{$self->{'-tempPiles'}}; my $i; foreach $i ( @cp ) { return if ($#{$i->{'-contents'}} == -1); } $self->{'-board'}->log_commit(0); foreach $i ( @cp ) { $i->do_merge($self->do_split(-1)); } } # package FinishCardPile; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK ); require Exporter; require AutoLoader; @ISA = qw(Exporter AutoLoader CardPlay::CardPile); @EXPORT = qw( ); $VERSION = "0.2"; use Tk; use Carp; use CardPlay::Card; use CardPlay::CardPile; use CardPlay::CardBoard; sub new { my $type = shift; my $self = CardPlay::CardPile->new(@_); $self->{'-mergeable'}=1; $self->{'-deltay'}=0; bless $self; } sub can_merge { my ($self,$cardpile) = @_; my (@contents) = @{$cardpile->{'-contents'}}; return 0 if ($cardpile->empty()); return 0 if (! $self->empty()); my $suit = $contents[0]->{'-suit'}; my $number = 13; for(my $i=0;$i<=$#contents;$i++) { return 0 if (!defined($contents[$i])); return 0 if ($contents[$i]->{'-suit'} ne $suit); return 0 if ($contents[$i]->{'-number'} != $number); $number--; } return 0 if ($number!=0); return 1; } package SpiderBoard; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK @count ); require Exporter; require AutoLoader; @ISA = qw(Exporter AutoLoader CardPlay::CardBoard); @EXPORT = qw( ); $VERSION = "0.2"; use Tk; use Carp; use CardPlay::Card; use CardPlay::CardPile; use CardPlay::CardBoard; sub new { my $type = shift; my $self = CardPlay::CardBoard->new(@_); bless $self; } sub new_cards { my $self = shift; my $card = []; my ($i,$j,$suit); my ($c) = $self->{'-canvas'}; for($j=0;$j<2;$j++) { foreach $suit ( 's','h','c','d') { for($i=1;$i<14;$i++) { push(@{$card},CardPlay::Card->new( -canvas=>$c,-board=>$self,-suit=>$suit,-number=>$i)); } } } $self->{'-cards'} = $card; $self; } @count = (6,5,5,6,5,5,6,5,5,6); sub display { my $self = shift; $self->SUPER::display( -title=>'Spider'); my $c = $self->{'-canvas'}; my $x = $CardPlay::Card::cx+10; my $y = 20; my @finish; my $i; $self->{'-mainWindow'}->geometry( sprintf("%dx%d",($CardPlay::Card::cx+10)*10,600)); $self->new_cards; for($i=0;$i<8;$i++) { $finish[$i] = FinishCardPile->new(-canvas=>$c,-base=>1,-board=>$self); $finish[$i]->display('-x'=>$x,'-y'=>$y); $x += $CardPlay::Card::cx+5; } $self->{'-finishPiles'} = \@finish; $self->add_piles(@finish); $x = 5; $y = 20; my $dl = DealCardPile->new(-canvas=>$c,-base=>1,-board=>$self); $dl->display('-x'=>$x,'-y'=>$y); $self->{'-dealPile'} = $dl; $self->add_piles($dl); $x = 5; $y = $y+$CardPlay::Card::cy+10; my @cp; for($i=0;$i<=$#count;$i++) { $cp[$i] = TempCardPile->new( -canvas=>$c,-auto_open=>1,-board=>$self, -tempPiles=>\@cp); $cp[$i]->display('-x'=>$x,'-y'=>$y,-base=>1); $x += $CardPlay::Card::cx+5; } $dl->{'-tempPiles'} = \@cp; $self->{'-tempPiles'} = \@cp; $self->add_piles(@cp); $self; } sub setup { my $self = shift; my ($dl) = $self->{'-dealPile'}; my ($cp) = $self->{'-tempPiles'}; my ($fi) = $self->{'-finishPiles'}; my ($i,$j); # remove all CardPile $self->clear; # make new board by saved card array @{$dl->{'-contents'}} = @{$self->{'-cards'}}; # copy $dl->close_all(); for($i=0;$i<=$#count;$i++) { $j = $cp->[$i]; $j->merge($dl->split(- $count[$i])); $j->open(); } $self; } # end package main; use strict; use CardPlay::CardBoard; my $board = SpiderBoard->new(); $board->game(); 1; # end