function bugs out

Discussion in 'JavaScript' started by manjolo, Sep 29, 2010.

  1. #1
    Hello.

    Ive been making a little game called Pig with a very simple ai algorithm but i have a bug that is killing me and i cant fix it.
    so i have to buttons roll and hold. when i roll i sum up my rolls and if i hit hold i save them to my counter and pass turn to computer. if i roll 1 then my total will drop to 0 and turn is passed to comp. all works great till i have to declare winner. declaration is done properly when i win or computer wins after i press hold. problems comes when i hit roll and get 1 (which passes turn to comp) and within his turn computer wins. when this happens winner is not declared. the weirdest thing is that all 3 declarations are done with very same function.
    heres the code:

    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Pig</title>
    <link href="sstyle.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
    
    var totalSc = 0;
    var playerSc = 0;
    var compSc = 0;
    
    
    function toggleLog (i) {
    	document.getElementById('logMsg').style.display = (i) ? "block" : "none";
    	document.getElementById('logSwitch').innerHTML = (i) ? 
    		"<a href=\"javascript:toggleLog();\">Hide log</a>" : 
    		"<a href=\"javascript:toggleLog(1);\">Show log</a>";	
    }
    
    function rollLog (msg) {
    	var divTag = document.createElement("option");
    	divTag.innerHTML = msg;
    	document.getElementById('logMsg').insertBefore(divTag, document.getElementById('logMsg').firstChild);
    }
    
    function toggleButton (i) {
    	var a;
    	
    	if (i == 1) {a = false}
    	else {a = "disabled"}
    	
    	document.getElementById('roll').disabled = a;
    	document.getElementById('hold').disabled = a;
    }
    
    
    function newGame(who) {
    	var actor = (who == "c") ? "Computer" : "You";
    	document.getElementById('buttons').innerHTML = "<input type=\"button\" value=\"New Game\" onclick=\"resetGame()\">";
    	rollLog(actor+" won!");
    	document.getElementById('totalSc').innerHTML = actor+" won!";
    }
    function resetGame () {
    	totalSc = 0;
    	playerSc = 0;
    	compSc = 0;
    	document.getElementById('playerSc').innerHTML = playerSc;
    	document.getElementById('totalSc').innerHTML = totalSc;
    	document.getElementById('compSc').innerHTML = compSc;
    	document.getElementById('compBar').style.width = "1%";
    	document.getElementById('playerBar').style.width = "1%";
    
    	document.getElementById('buttons').innerHTML = "<input type=\"button\" name=\"Roll\" id=\"roll\" value=\"Roll\" onclick=\"rollDice()\" />   <input type=\"button\" name=\"Hold\" id=\"hold\" value=\"Hold\" onclick=\"holdTurn()\" />";
    	rollLog("New Game!");
    	
    }
    
    function saveSc (who) {
    	if (who == "c") {
    		compSc = compSc + totalSc;
    		document.getElementById('compSc').innerHTML = compSc;
    		document.getElementById('compBar').style.width = (compSc >= 100) ? 100 + "%" : compSc + "%";
    
    	} else {
    		playerSc = playerSc + totalSc;
    		document.getElementById('playerSc').innerHTML = playerSc;
    		document.getElementById('playerBar').style.width = (playerSc >= 100) ? 100 + "%" : playerSc + "%";
    
    	}
    	totalSc = 0;
    	document.getElementById('totalSc').innerHTML = totalSc;
    }
    
    function rollDice (who) {
    	
    	var actor = (who == "c") ? "Computer: " : "You: ";
    
    	var dice = Math.floor(Math.random() * 6) + 1;
    	//document.getElementById('dicePic').innerHTML = "<img src=images/"+dice+".jpg width=\"80\" height=\"80\">";
    	document.getElementById('dicePic').innerHTML = dice;
    	// add throw to log
    	rollLog(actor+dice);
    	
    	// if rolled 1 pass turn else att to total score
    	if (dice == 1) {
    		totalSc = 0;
    		if (who == "c") { toggleButton(1); } 
    		else { compTurn(); }		
    	} else {
    		totalSc = totalSc + dice;
    	}
    	
    	document.getElementById('totalSc').innerHTML = totalSc;
    	
    }
    
    function holdTurn () 
    {
    	saveSc();
    	// if total score is >= 100 declare win for player
    	if (playerSc >= 100) { newGame(); }
    	
    	// if total score is < 100 pass turn to comp
    	else { compTurn(); }
    }
    
    function compTurn () {
    	
    	// deactivate buttons at start of computer turn
    	toggleButton();
    	var dice;
    	
    	do {
    		// roll dice and display total score
    		rollDice("c");
    		document.getElementById('totalSc').innerHTML = totalSc;
    	
    		if (totalSc >= 20 || (totalSc + compSc) >= 100) {
    			// if total score is more than 20 or more than 100 save, activate buttons and break out
    			saveSc("c");
    			
    				// if total score is >=100 declare win for comp and break out
    				if (compSc >= 100) {
    					newGame("c");
    					break;
    				}
    
    			toggleButton(1);
    			break;
    		} 
    		
    		// if total score is 0 break out and activate buttons
    		if (totalSc == 0){
    			toggleButton(1);
    			break;
    		}
    		
    
    	}
    	while (totalSc <= 20)
    }
    
    
    </script>
    </head>
    <body>
    <div id="wrapper">
    	<form id="form1" name="form1" method="post" action="">
    		<table border="0">
    			<tr>
    				<td colspan="3">Total:<br />
    					<span id="totalSc">0</span></td>
    			</tr>
    			<tr>
    				<td colspan="3"><div id="testBar"></div></td>
    			</tr>
    			<tr>
    				<td colspan="3"><div id="playerBar"></div>
    					<div id="compBar"></div></td>
    			</tr>
    			<tr>
    				<td>You:<br />
    					<span id="playerSc">0</span></td>
    				<td><div id="dicePic" style="text-align:center; font-weight:bold">0</div></td>
    				<td>Comp:<br />
    					<span id="compSc">0</span></td>
    			</tr>
    			<tr>
    				<td>&nbsp;</td>
    				<td id="buttons"><input type="button" name="Roll" id="roll" value="Roll" onclick="rollDice()" />
    					<input type="button" name="Hold" id="hold" value="Hold" onclick="holdTurn()" /></td>
    				<td>&nbsp;</td>
    			</tr>
    		</table>
    		<div id="logSwitch"><a href="javascript:toggleLog(1);">Show log</a></div>
    		<select name="log" multiple="multiple" size="10" id="logMsg" style="display: none">
    			<option>Result Log</option>
    		</select>
    	</form>
    </div>
    </body>
    </html>
    
    Code (markup):
     
    Last edited: Sep 29, 2010
    manjolo, Sep 29, 2010 IP
  2. lazycoder

    lazycoder Peon

    Messages:
    11
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #2
    I can't reproduce the bug. The winner is always declared even under circumstances you describe.
     
    lazycoder, Sep 29, 2010 IP
  3. manjolo

    manjolo Peon

    Messages:
    4
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    ye i forgot to mention. in log it is always declared but i need it to be declared at the top where the total score is displayed during game because log is for dev purposes and will be lost eventually.
    try hitting hold till computer wins (you'll see winner declared) and then next game hit roll till computer wins (you'll see 0 instead of winner, but log will state that comp won).

    PS also another thing that i cant figure out is how to make rolling a dice take time (for instance 1 sec). i tried to put setTiomeout() around rollDice() function but it didnt work.
     
    manjolo, Sep 29, 2010 IP
  4. manjolo

    manjolo Peon

    Messages:
    4
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    shamless bump :(
     
    manjolo, Oct 4, 2010 IP
  5. lazycoder

    lazycoder Peon

    Messages:
    11
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    The winner message is always shown on top, but it is immediately overwritten in end of rollDice() function. You can create a gameInProgress variable, set it to true in resetGame(), to false in newGame() and update 'totalSc' in rollDice() only when gameInProgress is false.

    About the timer. Rename rollDice(who) to doRollDice(who). Then create:
    
    function rollDice(who)
        {
            //Disable buttons and show some "rolling..." message here.
    
            setTimeout(function() { doRollDice(who) }, 3000); //wait 3 seconds
        }
    
    Code (markup):
    Enable buttons again in doRollDice function.

    it.expertmonster.com - Q&A Forum
     
    lazycoder, Oct 4, 2010 IP
  6. manjolo

    manjolo Peon

    Messages:
    4
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #6
    thnx alot, i know the direction now, some tweaking and im done :)
     
    manjolo, Oct 4, 2010 IP
  7. lazycoder

    lazycoder Peon

    Messages:
    11
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    you are welcome
     
    lazycoder, Oct 4, 2010 IP