|
Programmer
Join Date: Jul 2005
Posts: 62
Rep Power: 4 
|
Tic-Tac-Toe
Well, I've made my tic-tac-toe game, but instead of fully searching the tree, I only went 5 moves ahead. The problem is that it is making some dumb mistakes, like blocking my moves instead of taking the wins. Here's the script + HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Tic-Tac-Toe</title>
<style type="text/css">
<!--
td
{
width: 50px;
height: 50px;
text-align: center;
background-color: white;
font-size: 40;
}
//-->
</style>
<script type="text/javascript">
<!--
//The number of turns in
var turnsIn = 0;
//Array for available spots
var spotsLeft = new Array(1,2,3,4,5,6,7,8,9);
//Marker for person
var enemyMarker = "X";
//Marker for computer
var allyMarker = "O";
//Arrays of different possibilities to win
//Last 2 slots in each array are for the totals of wins
var winPoss = new Array();
winPoss[0] = new Array(1,2,3,0,0);
winPoss[1] = new Array(4,5,6,0,0);
winPoss[2] = new Array(7,8,9,0,0);
winPoss[3] = new Array(1,4,7,0,0);
winPoss[4] = new Array(2,5,8,0,0);
winPoss[5] = new Array(3,6,9,0,0);
winPoss[6] = new Array(1,5,9,0,0);
winPoss[7] = new Array(3,5,7,0,0);
function makeMove(player,spot)
{
//Get the right array number based upon player
wNum = (player == "h")? 3:4;
//Go through array winPoss
for(w=0;w<winPoss.length;w++){
//Go through array winPoss[w]
for(wP=0;wP<3;wP++){
//If the array number is equal to the spot, increment the array num
if(winPoss[w][wP] == spot) winPoss[w][wNum]++;
}
}
//Remove spot from array
spotsLeft[spot-1] = '0';
//Increment the number of turns
turnsIn++;
}
function undoMove(player,spot)
{
//Get the right array number based upon player
var wNum = (player == "h")? 3:4;
//Loop through array winPoss
for(w=0;w<winPoss.length;w++){
//Loop through array winPoss[w]
for(wP=0;wP<3;wP++){
//If the array number is equal to the spot, decrement the array num
if(winPoss[w][wP] == spot) winPoss[w][wNum]--;
}
}
//Add spot to array
spotsLeft[spot-1] = spot;
//Decrement turnsIn
turnsIn--;
}
function checkWin()
{
//Checsk to see if either player has not won
for(w=0;w<winPoss.length;w++){
if(winPoss[w][3] == 3 || winPoss[w][4] == 3) return 0;
}
return 1;
}
function evaluate()
{
//Evaluates the score of the position
var score=0;
//Go through winPoss
for(w=0;w<winPoss.length;w++){
if(winPoss[w][4] == 3) score += 30;
if(winPoss[w][4] == 2 && winPoss[w][3] == 0) score += 5;
if(winPoss[w][3] == 3) score -= 25;
if(winPoss[w][3] == 2 && winPoss[w][4] == 0) score -= 5;
}
return score;
}
function minmax(depth,player,treeTop){
//If at the bottom return the evaluation of the position
if(depth <= 0){
return evaluate();
}
//Set the player for the next move
var nextMove = (player == "h")? "c":"h";
//No current best move
var bestSpot = 0;
//Really low number just to make sure
var highestNum = -Infinity;
//Loop through the spots left
for(var a=0;a<9;a++) {
if(spotsLeft[a] != 0){ //If there really is a spot
//Set no win to one to get past the later check
var noWin = 1;
//Make the move
makeMove(player,a+1);
if(turnsIn >= 5){ //If the number of turns is an amount available to having won, check for a win
noWin = checkWin();
}
if(noWin){ //If nobody won
//Go through the possible moves
var val = -minmax(depth-1,nextMove,0);
if(val > highestNum){ //If the return is greater than the current highest number, change it
highestNum = val;
if(treeTop)
bestSpot = a+1; //Change the best spot
}
}else{ //If somebody won
val = 30;
if(val > highestNum){
highestNum = val; //Change the highest num
if(treeTop)
bestSpot = a+1; //Change the best spot
}
}
undoMove(player,a+1); //Undo the move
}
}
if(!treeTop){
return highestNum; //If it's not the top then return the highest number
}else{
alert(highestNum);
return bestSpot; //If it is the top then return the best spot
}
}
function allyReply()
{
//Go through the minmax function
goSpot = minmax(5,"c",1);
//Add the marker to the spot
document.getElementById(goSpot).innerHTML = allyMarker;
//Make the move
makeMove("c",goSpot);
//Check for a win
var noWin = checkWin();
if(!noWin) //If there is a win
alert("You've Lost!");
else if(turnsIn == 9) //If there is a cats game
alert("Cat's Game!");
else if(noWin && turnsIn < 9) //other wise allow enemy to go
enemyAct = 1;
}
function checkSpot(spot)
{
//Checks to make sure neither player already holds the spot in question
goodSpot = 0;
for(i=0;i<spotsLeft.length;i++){
if(spotsLeft[i] == spot) goodSpot = 1;
}
return goodSpot;
}
function addSpot(a)
{
//If it's the persons turn
if(enemyAct){
//Set tID as the id of the table cell clicked on
tID = a.id;
//If the spot is open
if(checkSpot(tID)){
//Don't let the user go again
enemyAct = 0;
//Put the marker in
a.innerHTML = enemyMarker;
//Make the move
makeMove("h",tID);
var noWin = checkWin();
if(!noWin)
alert("You win!");
else if(turnsIn == 9)
alert("Cat's Game!");
else if(noWin && turnsIn < 9) allyReply();
}else{
//If the spot is already taken
alert("That spot is already taken");
}
}else{
//If it's not the users turn
alert("It's not your turn.");
}
}
//-->
</script>
</head>
<body>
<table bgcolor="black" cellspacing="1" id="ttt">
<tr>
<td id="1" class="corner" onclick="javascript:addSpot(this);"></td>
<td id="2" class="edge" onclick="javascript:addSpot(this);"></td>
<td id="3" class="corner" onclick="javascript:addSpot(this);"></td>
</tr>
<tr>
<td id="4" class="edge" onclick="javascript:addSpot(this);"></td>
<td id="5" class="center" onclick="javascript:addSpot(this);"></td>
<td id="6" class="edge" onclick="javascript:addSpot(this);"></td>
</tr>
<tr>
<td id="7" class="corner" onclick="javascript:addSpot(this);"></td>
<td id="8" class="edge" onclick="javascript:addSpot(this);"></td>
<td id="9" class="corner" onclick="javascript:addSpot(this);"></td>
</tr>
</table>
<script type="text/javascript">
<!--
var enemyAct = 0;
var c = confirm("Would you like to go first?");
if(c) enemyAct = 1;
else allyReply();
//-->
</script>
</body>
</html> It can be viewed here:
http://digitalcs.net/tests/tictactoe3.htm
Thank you for any help, I have no clue why it's making these dumb moves, I was thinking that it might be the values I've associated with certain things could be better, but I'm not sure.
|