Giter Club home page Giter Club logo

tic-tac-toe-php's Introduction

tic-tac-toe-php

<?php

class Board {
    private $boardElements;
    public function __construct() {
        $this->boardElements = [
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]
        ];
    }

    public function getBoard() {
        return $this->boardElements;
    }

    public function draw() {
        foreach($this->boardElements as $rowIndex => $row) {
            foreach($row as $index => $element) {
                if ($element == 1) {
                    echo "O";
                } elseif($element == -1) {
                    echo "X";
                } else {
                    echo " ";
                }

                if($index != count($row) - 1) {
                    echo " | ";
                }
            }

            if($rowIndex != count($this->boardElements) - 1) {
                echo PHP_EOL . "---------" . PHP_EOL;
            }
        }

        echo PHP_EOL;
    }

    public function add($element, $i, $j) {
        $this->boardElements[$i][$j] = $element;
    }

    public function set($boardArray) {
        $this->boardElements = $boardArray;
    }

    public function check() {
        if ($this->checkIfElementWin(1)) {
            return "O";
        } else if ($this->checkIfElementWin(-1)) {
            return "X";
        } else if ($this->checkIfDone()) {
            return "Done";
        } else {
            return "Continue";
        }
    }

    private function checkIfDone() {
        foreach($this->boardElements as $row) {
            foreach($row as $element) {
                if ($element == 0) {
                    return false;
                }
            }
        }

        return true;
    } 

    private function checkIfElementWin($element) {
        for ($i=0; $i < 3; $i++) { 
            if (($this->boardElements[$i][0] == $element) &&
                ($this->boardElements[$i][1] == $element) &&
                ($this->boardElements[$i][2] == $element)) {
                    return true;
            }
        }

        for ($i=0; $i < 3; $i++) { 
            if (($this->boardElements[0][$i] == $element) &&
                ($this->boardElements[1][$i] == $element) &&
                ($this->boardElements[2][$i] == $element)) {
                    return true;
            }
        }

        if (($this->boardElements[0][0] == $element) &&
            ($this->boardElements[1][1] == $element) &&
            ($this->boardElements[2][2] == $element)) {
                return true;
        }

        if (($this->boardElements[0][2] == $element) &&
            ($this->boardElements[1][1] == $element) &&
            ($this->boardElements[2][0] == $element)) {
                return true;
        }

        return false;
    }
}

class RandomPlayer {
    public function nextMove($board, $myElement) {
        $board = $board->getBoard();
        $nextMoves = [];
        foreach($board as $i => $row) {
            foreach($row as $j => $element) {
                if ($element == 0) {
                    $nextMoves[] = [$i, $j];
                }
            }
        }

        if (count($nextMoves) == 0)
            return [];

        return [$myElement, $nextMoves[array_rand($nextMoves)]];
    }
}

class aiPlayer {
    public function nextMove($board, $myElement, $true = true) {
        $bestVal = -1000;
        $bestMove = [-1, -1];

        $boardData = $board->getBoard();
        foreach($boardData as $i => $row) {
            foreach($row as $j => $element) {
                if ($element == 0) {
                    $cBoard = clone $board;
                    $cBoard->add($myElement, $i, $j);
                    $moveVal = $this->maxMin($cBoard, $myElement, !$true, 0,$myElement * -1);
                    // echo $i .' - '. $j . ' : ' . $moveVal . PHP_EOL;

                    if ($moveVal > $bestVal) {
                        $bestVal = $moveVal;
                        $bestMove = [$i, $j];
                    }
                }
            }
        }
        return [$myElement, $bestMove];
    }

    private function maxMin($board, $myElement, $maxOrMin, $depth, $temp)
    {
        if ($myElement == -1) {
            if ($board->check() == 'X') {
                return 1 - $depth * 0.1;
            } elseif ($board->check() == 'O') {
                return $depth * 0.1 - 1;
            } elseif ($board->check() == 'Done') {
                return 0;
            }
        }

        if ($myElement == 1) {
            if ($board->check() == 'X') {
                return $depth * 0.1 - 1;
            } elseif ($board->check() == 'O') {
                return 1 - $depth * 0.1;
            } elseif ($board->check() == 'Done') {
                return 0;
            }
        }

        $value = $maxOrMin ? -20000 : +20000;
        $boardData = $board->getBoard();
        foreach($boardData as $i => $row) {
            foreach($row as $j => $element) {
                if ($element == 0) {
                    $cBoard = clone $board;
                    $cBoard->add($temp, $i, $j);
                    $maxOrMinValue = $this->maxMin($cBoard, $myElement, !$maxOrMin, $depth + 1, $temp * -1);
                    if ($maxOrMin) {
                        if ($maxOrMinValue > $value) {
                            $value = $maxOrMinValue;
                        }
                    } else {
                        if ($maxOrMinValue < $value) {
                            $value = $maxOrMinValue;
                        }
                    }
                }
            }
        }
        return $value;
    }
}

$randomPlayerOne = new RandomPlayer();
$randomPlayerTwo = new RandomPlayer();
$aiPlayerOne = new aiPlayer();

$board = new Board();

while ($board->check() == "Continue") {
    $randomPlayerOneMove = $randomPlayerOne->nextMove($board, -1);
    if (count($randomPlayerOneMove) != 0)
        $board->add($randomPlayerOneMove[0], $randomPlayerOneMove[1][0], $randomPlayerOneMove[1][1]);

    $randomPlayerTwoMove = $aiPlayerOne->nextMove($board, 1);
    if (count($randomPlayerTwoMove) != 0)
        $board->add($randomPlayerTwoMove[0], $randomPlayerTwoMove[1][0], $randomPlayerTwoMove[1][1]);
}

$board->draw();
if ($board->check() == "O") {
    echo "O wins";
} elseif($board->check() == "Done") {
    echo "Tie";
}
echo PHP_EOL;

output

O | X |  
---------
  | O |  
---------
X | X | O
O wins

tic-tac-toe-php's People

Contributors

azibom avatar

Stargazers

Alireza Shabani avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.