Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jul 14th, 2005, 4:26 PM   #1
Eryk
Programmer
 
Join Date: Jul 2005
Posts: 62
Rep Power: 4 Eryk is on a distinguished road
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.
Eryk is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 6:32 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC