Posts Tagged ‘tic tac toe’

Tic Tac Toe

22. May 2009

1 Comment »

A graphical Tic Tac Toe board using PHP-Gtk

#!/usr/local/bin/php -q
<?php
class TicTacToe extends GtkWindow{

    private $_buttons;
    private $_dialog;
    private $_count;
    private $_menu;
    private $_lbl;

    public function __construct()
    {
        parent::__construct();

        $this->set_title('Tic-Tac-Toe');
        $this->set_size_request(250, 250);
        $this->set_position(Gtk::WIN_POS_CENTER);
        $this->connect_simple('destroy', array('gtk', 'main_quit'));

        #Create the Buttons and add them to the table
        for($i = 0; $i < 9; $i++) {
            $this->_buttons[$i] = new GtkButton('');
            $this->_buttons[$i]->connect_simple('clicked', array($this, 'clicked'), $i);
        }

        #Create a GtkTable
        $tbl = new GtkTable(3, 3);

        #Add nine buttons to the table
        for($i = 0; $i < 9; $i++) {
            $tbl->attach($this->_buttons[$i], ($i%3), ($i%3)+1, floor($i/3), floor($i/3)+1);
        }

        $this->buildMenu();

        #GtkStatusBar
        $status = new GtkStatusbar();
        $context = array('Not Connected', 'Connected');
        $status->push($status->get_context_id($context[0]), $context[0]);

        #GtkVBox
        $vbox = new GtkVBox();
        #Add the GtkVBox to the main window
        $this->add($vbox);
        #Add the GtkMenu to the GtkVBox
        $vbox->pack_start($this->_menu, false);
        #Add the GtkTable to the GtkVBox
        $vbox->pack_start($tbl, true, true);
        #Add the GtkStatusBar to the GtkVBox
        $vbox->pack_start($status, false);

        $this->show_all();

        $this->server();

    }

    private function server()
    {
        #Not implemented
    }

    private function buildMenu()
    {
        #GtkMenu
        $this->_menu = new GtkMenuBar();
        $this->_menu->append($file_item = new GtkMenuItem('_File'));
        $this->_menu->append($help_item = new GtkMenuItem('_Help'));

        $file_item->set_submenu($file_menu = new  GtkMenu());
        $file_menu->append($file_new_item = new GtkMenuItem('_New'));
        $file_menu->append($file_connect_item = new GtkMenuItem('_Connect'));
        $file_menu->append($file_quit_item = new GtkMenuItem('_Quit'));

         $help_item->set_submenu($help_menu = new  GtkMenu());
        $help_menu->append($help_about_item = new GtkMenuItem('_About'));

        $file_new_item->connect_simple('activate', array($this,'restart'));
        $help_about_item->connect_simple('activate', array($this,'about'));
        $file_quit_item->connect_simple('activate', array('Gtk','main_quit'));
    }

    public function about()
    {
        $about = new GtkAboutDialog();
        $about->set_authors(array("John Ciacia"));
        $about->set_comments("Tic-Tac-Toe created using the PHP-Gtk extension.");
        $about->set_copyright("Copyright (C) 2008 John Ciacia");
        $about->set_license("This software is released under the GNU GPL");
        $about->set_version("1.0");
        $about->set_website("http://www.codecall.net");
        $about->set_website_label("http://www.codecall.net");
        $about->show_all();
    }

    public function clicked($i)
    {
        !isset($this->_count) ? $this->_count = 0 : $this->_count++;
        ($this->_count % 2 == 0) ? $this->_lbl = 'X' : $this->_lbl = 'O';

        $this->_buttons[$i]->set_label($this->_lbl);
        $this->_buttons[$i]->set_sensitive(false);

        $this->_check();
    }

    private function _check()
    {
        $win = false;

        $combinations = array(
            0 => array(0, 1, 2),
            1 => array(3, 4, 5),
            2 => array(6, 7, 8),

            3 => array(0, 3, 6),
            4 => array(1, 4, 7),
            5 => array(2, 5, 8),

            6 => array(0, 4, 8),
            7 => array(2, 4, 6));

        for($i = 0; $i < 8; $i++)
        {
            if( ($this->_buttons[$combinations[$i][0]]->get_label() ==
                    $this->_buttons[$combinations[$i][1]]->get_label()) && 

                ($this->_buttons[$combinations[$i][1]]->get_label() ==
                    $this->_buttons[$combinations[$i][2]]->get_label()) && 

                ($this->_buttons[$combinations[$i][0]]->get_label() != "")){

                $win = true;
            }
        }

        if($win) {
            $this->end_dialog(true);
        }
        else if(!$win && $this->_count == 8) {
            $this->end_dialog();
        }
        else {
            ;
        }
    }

    private function end_dialog($win = false){

        $this->_dialog = new GtkDialog(null, $this);
        $this->_dialog->set_title("Play Again?");
        $this->_dialog->set_default_size('100','100');
        $this->_dialog->set_modal(true);
        $this->_dialog->set_transient_for($this);
        $this->_dialog->set_resizable(false);
        $this->_dialog->connect_simple('destroy', array($this, 'destroy'));
        if($win) {
            $label = new GtkLabel($this->_lbl . " has won the game. Play again?");
        } else {
            $label = new GtkLabel("It's a tie! Play again?");
        }
        $button_yes = new GtkButton('_Yes');
        $button_yes->connect_simple('clicked', array($this, 'restart'));
        $button_no = new GtkButton('_No');
        $button_no->connect('clicked', array($this, 'destroy'));

        $vbox1 = $this->_dialog->vbox;
        $vbox2 = $this->_dialog->action_area;
        $vbox1->pack_start($label);
        $vbox2->pack_start($button_yes);
        $vbox2->pack_start($button_no);
        $this->_dialog->show_all();
    }

    public function restart()
    {
        if(isset($this->_dialog)) { $this->_dialog->hide_all(); }
        unset($this->_count);

        foreach($this->_buttons as $button):
            $button->set_label('');
            $button->set_sensitive(true);
        endforeach;
    }

    public function destroy()
    {
        echo "Good Bye!\n";
        Gtk::main_quit();
    }

}

new TicTacToe();
Gtk::main();

?>

tictactoe