====== Exemple 5 - a Marienbad Game ====== This one is a Marienbad Game ((The actual name is: Game of nim)) made with the [[winApp class]]. ===== Result ===== {{php_dhtml:marienbad.png?300}} ===== Code ===== * http://wildphp.free.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ include_once 'dhtml/winApp.inc'; $GLOBALS['WINAPP_RC_PATH']= '../rc/winapp_classic/'; class Marienbad extends winApp { var $title= ''; /* Configuration du jeu */ var $start_game= array( 1, 2, 3, 5, 7 ); var $game= array( 1, 2, 3, 5, 7 ); /* Parametre de la partie en cours */ var $current_col= -1; var $current_count= 0; var $current_player= 0; var $ia_player= 2; function Marienbad() { $this->title= 'Marienbad Game'; parent::winApp($this->title, false, true, '450x300'); } /** * Global Init */ function on_init() { $this->toolbar->add_button( 'app', 'File', 'buttons/new.png', array( 'start' => 'Play alone', 'login' => 'Remotly connect', '-', 'quit' => 'Quit', ) ); $this->toolbar->add_button( 'undo', 'Game', 'buttons/open.png', array('switch_players' => ' Player starts') , array('undo' => 'Undo') ); $this->toolbar->add_button( 'help', '', 'buttons/help.png', array( 'help_about' => 'About', 'help_about_php' => 'About Php' ) ); $this->handles_click('allumette', true); $this->handles_click('play'); $this->ia_player= 2; } function on_click( $id ) { if( !ereg('^image_([0-9]+)_([0-9]+)$', $id, $matches) ) return; if( $this->current_player==$this->ia_player ) { $this->set_status("Your opponent have played - click OK to continue"); return; } list($foo, $height, $col) = $matches; /* Row check */ if( $this->current_col!=-1 && $this->current_col!=$col ) { $this->set_warning("You have already played in ".$this->current_col); return; } else $this->current_col= $col; if( $this->current_count>=$this->game[$col] ) { $this->set_warning("All matches have been removed in ".$this->current_col); return; } $this->current_count++; $this->update_col($this->current_col); $this->set_status("Played in ".$this->current_col); } /** * Page loading */ function on_page_load($url) { parent::on_page_load($url); $this->id_html('window_frame', '
'); $this->start(); } function on_command_switch_players() { if( $this->ia_player==2 ) $this->ia_player= 1; else $this->ia_player= 2; if( $this->ia_player==2 ) $this->id_img_src('player_starts', 'buttons/checked.jpg'); else $this->id_img_src('player_starts', 'buttons/unchecked.jpg'); $this->start(); } function on_command_help_about() { new MessageBox($this, "Marienbad Game CopyLeft 2004.

The one that remove the last matche loose
You can remove any number of matches in the same column.
Note: The starting player has a BIG advantage.
Have Fun !", "About", false, '300x250'); } function on_command_help_about_php() { about_php($this); } function on_command_start() { $this->start(); } function on_command_play() { $this->play(); } function on_command_ia_play() { $this->ia_play(); } function on_command_quit() { $this->close(); } function on_command_login() { new MessageBox($this, '

Not implemented

'); } function start() { $this->current_player= 2; // So initial switching set it to 1 $this->current_col= -1; $this->current_count= 0; $this->game= $this->start_game; $this->new_round(); } function new_round() { if( !$this->current_player ) return; if( $this->current_player==1 ) $this->current_player= 2; else $this->current_player= 1; if( $this->count()==0 ) { // Fin du jeu $this->clear(); if( $this->current_player==$this->ia_player ) $this->write("

You loose ...
:-(
"); else $this->write("

Player Win !
:-)
"); $this->current_player= 0; return; } $this->display_table(); if( $this->current_player==$this->ia_player ) $this->ia_play(); } function play() { if( $this->current_col==-1 || !$this->current_count ) { $this->set_warning('Vous devez choisir une colonne dans laquelle enlever une ou plusieurs allumettes'); return; } $this->game[$this->current_col]-= $this->current_count; $this->current_col= -1; $this->current_count= 0; $this->set_status('Ready'); $this->new_round(); } function count() { $count= 0; foreach( $this->game as $k => $v ) { $count+= $v; } return $count; } function ia_play() { $ia= &new Marienbad_IA; list($col, $number)= $ia->best($this->game); $this->set_status("AI plays in: $col, $number"); //$this->player_action($col, $number); $this->current_col= $col; $this->current_count= $number; $this->update_cols(); } function update_cols() { for( $col= 0; $colgame); $col++ ) { $this->update_col($col); } } function update_col($col) { for( $i= $this->game[$col]-1; $i>=0; $i-- ) { if( $this->current_col==$col && $i>=$this->game[$col]-$this->current_count ) $this->id_img_src('image_'.$i.'_'.$col, realpath('images/allumette_off_h.gif')); else $this->id_img_src('image_'.$i.'_'.$col, realpath('images/allumette_h.gif')); } } function display_table() { $max= 7; if( $this->current_player==$this->ia_player ) $game.= "

IA turn (click ok)

"; else $game.= "

Player ".$this->current_player." it's your turn ".($this->current_player==$this->ia_player?"(IA)":'')."

"; $game.= ''; for( $i= $max-1; $i>=0; $i-- ) { $game.= ''; for( $col= 0; $colgame); $col++ ) { if( $this->game[$col]>$i ) { $game.= ''; } else { $game.= ''; } } $game.= ''; } $game.= '
'; if( $this->count() ) { $buttons.= ToolBar::build_button(array('play', '', "buttons/button_ok.gif")); } else { $buttons.= 'Fin !'; } $html= <<< EOHTML
$game
$buttons
EOHTML; $this->clear(); $this->write($html); } function clear() { $this->write_buffer= ''; $this->id_html('window', $this->write_buffer); } function write( $string ) { $this->write_buffer.= $string; $this->id_html('window_frame', $this->write_buffer); } function writeln( $string ) { $this->write( $string.'
' ); } } class Marienbad_IA { function best($game) { $col= $num= 0; $count= 0; $best_note= -1; // Get all possible $possible= array(); foreach( $game as $col => $value ) { //echo "$col => $value\n"; for($i= 1; $i<=$value; $i++ ) { $possible_game= $game; $possible_game[$col]-= $i; $note= $this->_eval($possible_game); if( $best_note<$note ) $best_note= $note; array_push($possible, array($col, $i, $note) ); } } if( $best_note==-1 ) // No possible choice return -1; // Get bests $bests= array(); for($i= 0; $i