This one is a Marienbad Game1) made with the winApp class.
<?php /** * php_dhtml * Copyright (C) 2004 Eric Colinet <e.colinet@laposte.net> * 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' => '<img id="player_starts" src="buttons/checked.jpg"> 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', '<div id="window"></div>'); $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.<br><br><i> The one that remove the last matche loose </i><br>You can remove any number of matches in the same column.<br>Note: The starting player has a <b>BIG</b> advantage.<br>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, '<h3>Not implemented</h3>'); } 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("<div align='center'><br/><font size='+3'color='red'>You loose ...<br>:-(</font></div>"); else $this->write("<div align='center'><br/><font size='+3' color='green'>Player Win !<br>:-)</font></div>"); $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; $col<count($this->game); $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.= "<H3>IA turn <font size=\"-2\">(click ok)</font></H3>"; else $game.= "<H3>Player ".$this->current_player." it's your turn ".($this->current_player==$this->ia_player?"(IA)":'')."</H3>"; $game.= '<TABLE border="0">'; for( $i= $max-1; $i>=0; $i-- ) { $game.= '<tr height="7">'; for( $col= 0; $col<count($this->game); $col++ ) { if( $this->game[$col]>$i ) { $game.= '<TD width="68" style="cursor: pointer" class="rows"><img class="allumette" id="image_'.$i.'_'.$col.'" src="'.realpath('images/allumette_h.gif').'" border="0"></TD>'; } else { $game.= '<TD width="68"><img id="image_'.$i.'_'.$col.'" src="'.realpath('images/allumette_black_v.gif').'" border="0"></TD>'; } } $game.= '</tr>'; } $game.= '</table>'; if( $this->count() ) { $buttons.= ToolBar::build_button(array('play', '', "buttons/button_ok.gif")); } else { $buttons.= '<font size="+2" color="green">Fin !</font>'; } $html= <<< EOHTML <center> <TABLE border="0" width="100%" height="100%"> <tr> <td align="center">$game</td> </tr> <tr> <td align="right" height="30">$buttons</td> </tr> </TABLE> 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.'<br/>' ); } } 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<count($possible); $i++) { if( $possible[$i][2]==$best_note ) array_push($bests, array($possible[$i][0], $possible[$i][1]) ); } // Randomly choose between bests $choose= mt_rand(0,count($bests)-1); return $bests[$choose]; } function _eval($game) { $count= 0; foreach( $game as $num ) { $count+= $num; } return $count%2*(20-$num); // Plus le nombre est bas plus la note est élevée (mmmh..) } } /* Go */ new Marienbad(); winApp::run(); ?>