

        
// show()      : shows the game situation as the machine remembers
// next()      : to check whose turn it is
// finished()  : Checks if the game is won by the last move
// act()       : Lets the machine decide which move to make when it is its turn
// Random()    : Generates a random number as specified (to make unpredictable moves)
// SelectRow() : Selects the row that the machines move will be to take from
// over()      : is called when it is the other sides turn

var nrInPiles0 = [ 1, 3, 5, 7 ];
var group = [ 1, 3, 5, 7 ];
var movenr = 0;
var game = '';
var gone = 0;
var players = 2;
var whos = 'your';
var whom = 'you';

// --- Refreshing the page after a move
// ---------------------------------------------------.
function show(movenr, part, g1, g2, g3, g4, groupnr, remove, taken) {
	gone = taken;
	game = game + ' ' + movenr + ':' + groupnr + '/' + remove;
	var kommentar = 'empty ';
	var titles = '<strong>group1 </strong>(' + g1 + ')';
	group[0] = g1;
	group[1] = g2;
	group[2] = g3;
	group[3] = g4;
	var groups = '' + group[0];
	for (g = 1; g < 4; g++) {
		groups = groups + ',' + group[g];
		titles = titles + '\n</td><td align="center">' + '\n<strong>group'
				+ (g + 1) + '</strong> (' + group[g] + ')';
	}
	//var win = window.open('','nim','resizable=yes,scrollbars=yes,width=500,height=600 ' );
	with (this.document) {
		open();
		write('<?xml version="1.0"?>');
		write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"');
		write('    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
		write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">');
		write('<head><title>NIM</title>');
		write('\n<meta http-equiv="Pragma" content="no-cache">');
		write('\n<script type="text/javascript" src="./nim.js" ></script>');
		write('\n<style  type="text/css"        src="./nim.css"></style>');
		write('\n</head>');
		write('\n<body><center><h2>NIM</h2>');

		//---------------------------- instructions ---------------------------------------------
		write('\n<table border="0" cellpadding="10">');
		write('\n<tr><td align="center">');
		write('\n<table border="0"><tr><td colspan="4" align="Left">');
		write('\nIn this game we (USER and MACHINE) take turns.<br/> ');
		write('\n<br/>When it is ones turn, one ..' 
				+ '\n<br/> - choses a non-empty group out of the four groups below' 
				+ '\n<br/> - removes at least one item (by clicking at the topmost one of those to go)' 
				+ '\n<br/>');
		write('\n<br/>Choices are clickable, usual ones are highlighted with pink background<br/>');
		write('\n<br/>The one who REMOVES THE LAST item WINS! <br/>');

		write('\n</td></tr></table>');
		write('\n</td></tr><tr><td>');
		write('\n<table border="0" width="100%">');

		//---------------------------- items on board  -------------------------------------------
		write('\n<tr><td align="center" valign="bottom">' + titles + '\n</td>');
		write('</tr><tr>');
		for (i = 0; i < 4; i++) { // groups remaining
			if (remove == 0) {
				write('<td align="center" valign="top" height="150" bgcolor="pink">&nbsp;');
				for (j = 0; j < group[i]; j++) { // items remaining
					if (j == group[i] - 1) {
						kommentar = 'remove this from group' + (i + 1);
					} else if (j == 0) {
						kommentar = 'empty group' + (i + 1);
					} else {
						kommentar = 'remove ' + (group[i] - j) + ' from group'
								+ (i + 1);
					}
					write('\n<br/><a href="Javascript:over(' + movenr + ','
							+ part + ',' + groups + ',' + i + ','
							+ (group[i] - j) + ',' + gone + ');">'
							+ '<img src="item.gif" border="0" alt="'
							+ kommentar + '"></a>');
				}
				write('\n</td>');
			} else {
				write('<td align="center" valign="top" height="150">&nbsp;');
				for (j = 0; j < group[i]; j++) { // items remaining
					write('\n<br/><img src="item.gif" border="0" ' 
							+ 'alt="Click the move-link down below to clear for your move" ' 
							+ 'onClick="{alert(\'Click the move-link down below to clear for your move\');}">');
				}
				write('\n</td>');
			}
		}
		write('</tr>');

		//----------------------- buttons for next move  ----------------------------------------
		write('\n<tr>');

		//------------------- new game ------
		if (group[0] == 1 && group[1] == 3 && group[2] == 5 && group[3] == 7) {
			write('\n<td align="center">' 
					+ '<a href="Javascript:{movenr=1;over(0,0,1,3,5,7,0,0,0);}">MACHINE first</a></td>');
			write('\n<td align="center"                                    >new game</td>');
		} else {
			//------------------- you first -----
			write('\n<td align="center"                                    >MACHINE first</td>');
			if (finished(g1, g2, g3, g4)) {
				write('\n<td align="center">' 
					+ '<a href="Javascript:{movenr=0;over(0,1,1,3,5,7,0,0,0);}">new game</a></td>');
			} else {
				write('\n<td align="center" >' 
					+ '<a href="Javascript:{movenr=0;over(0,1,1,3,5,7,0,0,0);}">new game</a></td>');
			}
		}
		if (remove > 0 && ((g1 + g2 + g3 + g4) != 0)) {
			if (part == 1) {
				//------------------- next you ------
				write('\n<td align="center" bgcolor="pink"><a onClick="{JavaScript:over('
						+ movenr
						+ ','
						+ next(part)
						+ ','
						+ group[0]
						+ ','
						+ group[1]
						+ ','
						+ group[2]
						+ ','
						+ group[3]
						+ ',0,0,'
						+ (gone + remove) + ');}" ');
				write('<strong>Next: MACHINE</strong></a></td>');
				write('\n<td align="center">next: USER</td>');
			} else {
				//------------------- next me -------
				write('\n<td align="center">next: MACHINE</td>');
				write('\n<td align="center" bgcolor="pink"><a onClick="{JavaScript:over('
						+ movenr
						+ ','
						+ next(part)
						+ ','
						+ group[0]
						+ ','
						+ group[1]
						+ ','
						+ group[2]
						+ ','
						+ group[3]
						+ ',0,0,'
						+ (gone + remove) + ');}" ');
				write('<strong>next: USER</strong></a></td>');
			}
			write('\n</tr>');

			//----------------------- items newly removed ----------------------------------------
			write('\n<tr height="150">');
			for (k = 0; k < 4; k++) {
				write('<td align="center" valign="bottom">&nbsp;');
				if (k == groupnr) {
					for (p = 0; p < remove; p++) {
						write('\n<br/><img SRC="item.gif"> ');
					}
				}
				write('\n</td>');
			}
			write('\n</tr>');

			//------------------------------ end of game?  ---------------------------------------
		} else {
			write('\n<td align="center">next: MACHINE</td>');
			write('\n<td align="center">next: USER</td>');

			if (finished(g1, g2, g3, g4)) {
				write('<tr height="150"><td colspan="4" valign="middle" align="center"><h1><br/><br/>');
				if (part == 1) {
					write('USER WINS!!!');
				} else {
					write('MACHINE WINS');
				}
				write('</h1></td></tr>');
			} else {
				write('<tr height="150"><td align="center">&nbsp;</td>');
				write('\n<td align="center">&nbsp;</td>');
				write('\n<td align="center">&nbsp;</td>');
				write('\n<td align="center">&nbsp;</td></tr>');
			}
		}
		//---------------------- items previously removed  --------------------------------------
		write('<tr><td align="left">Out<br/>(' + gone + ')<br/></td>');
		write('<td colspan="3" valign="top" align="left"> &nbsp;');
		for (p = 0; p < gone; p++) {
			write('\n <img src="item.gif" border="0" alt="these are already taken"/>');
			if (p == 8) {
				write('\n <br/>');
			}
		}
		write('</td></tr>');

		//---------------------- game history  --------------------------------------
		//write('<tr><td colspan="4" valign="top" align="left">&nbsp;'+game+'</td></tr>');

		write('\n</table></td></tr></table>');
		write('\n</center></body></html>');
		close();          // alert('OK so far');
	} //with (this.document)
} // show

//--- whose move.
function next(part) {
	if (part == (players - 1)) {
		part = 0;
	} else {
		part = part + 1;
	} //2 players;  0:computer, 1:user
	return part;
}// next

function finished(g1, g2, g3, g4) {
	if (g1 == 0 && g2 == 0 && g3 == 0 && g4 == 0) {
		return true;
	}
} // finished

//--- receiving a move ------------------------------------------------------------
function over(movenr, part, g1, g2, g3, g4, groupnr, remove, taken) // debug code
{ // alert('just in over('+movenr+','+part+','+g1+','+g2+','+g3+','+g4+','+groupnr+','+remove+')');
	movenumber = movenr;
	if (remove != 0) { // alert('next in over: remove!=0, show the move');
		if (groupnr == 0 && remove <= g1) { 
// alert('change2:show('+movenr+','+part+','+(g1-remove)+','+g2+','+g3+','+g4+',0,'+remove+',taken)');
			show(movenr, part, (g1 - remove), g2, g3, g4, 0, remove, taken);
		} else {
			if (groupnr == 1 && remove <= g2) { 
// alert('change2:show('+movenr+','+part+','+g1+','+(g2-remove)+','+g3+','+g4+',1,'+remove+',taken)');
				show(movenr, part, g1, (g2 - remove), g3, g4, 1, remove, taken);
			} else {
				if (groupnr == 2 && remove <= g3) { 
// alert('change2:show('+movenr+','+part+','+g1+','+g2+','+(g3-remove)+','+g4+',2,'+remove+',taken)');
					show(movenr, part, g1, g2, (g3 - remove), g4, 2, remove, taken);
				} else {
					if (groupnr == 3 && remove <= g4) { 
// alert('change2:show('+movenr+','+part+','+g1+','+g2+','+g3+','+(g4-remove)+',3,'+remove+',taken)');
						show(movenr, part, g1, g2, g3, (g4 - remove), 3, remove, taken);
					} else {
						alert('Attempt to remove '
								+ remove
								+ ' from group'
								+ groupnr
								+ ' is not acceptable. Legal moves are clickable.');
// alert('back2:show('+movenr+','+part+','+g1+','+g2+','+g3+','+g4+',0,0,taken)');
						show(movenr, part, g1, g2, g3, g4, 0, 0, taken);
					}
				}
			}
		}
	} else { // alert('not-over-yet');
		if (movenr == 0 && part == 1 && g1 == 1 && g2 == 3 && g3 == 5
				&& g4 == 7 && groupnr == 0 && remove == 0) { 
// alert('restarting');
			show(movenr, 1, 1, 3, 5, 7, 0, 0, taken);
		} else if (groupnr == 0 && remove == 0) { 
// alert('clearing');
			show(movenr, part, g1, g2, g3, g4, 0, 0, taken);
		}
		if (part == 0) { 
// alert('My turn!');
			act(g1, g2, g3, g4);
			movenumber = movenumber + 1;
			if (group[0] != g1) { 
// alert('I select group 1, and remove '+(g1-group[0])+' from it.');
				show(movenumber, 0, group[0], group[1], group[2], group[3], 0,
						(g1 - group[0]), taken);
			} else if (group[1] != g2) { 
// alert('I select group 2, and remove '+(g2-group[1])+' from it.');
				show(movenumber, 0, group[0], group[1], group[2], group[3], 1,
						(g2 - group[1]), taken);
			} else if (group[2] != g3) { 
// alert('I select group 3, and remove '+(g3-group[2])+' from it.');
				show(movenumber, 0, group[0], group[1], group[2], group[3], 2,
						(g3 - group[2]), taken);
			} else if (group[3] != g4) { 
// alert('I select group 4, and remove '+(g4-group[3])+' from it.');
				show(movenumber, 0, group[0], group[1], group[2], group[3], 3,
						(g4 - group[3]), taken);
			} else {
				alert('no group, -->can not figure out my next move');
			}
			part = next(part);
// alert('click to clear my move!');
		} else {
			show((movenr + 1), part, g1, g2, g3, g4, 0, 0, taken);
// alert('Your turn!');
		}
	}
}// over

//--- This player (part 0 = computer) makes a move.---------------------------------------------
function act(g1, g2, g3, g4) {
	group[0] = g1;
	group[1] = g2;
	group[2] = g3;
	group[3] = g4; 
// alert('This how I figure out my move: ');
	//--- here is the heart of the logic
	X = group[0] ^ group[1] ^ group[2] ^ group[3]; 
// alert('I calculate the -exclusive or- of the numbers in the groups '
//		+g1+','+g2+','+g3+','+g4+' and see that it is :'+X);
	if (X == 0) { 
// alert('Zero means you can win, so I play random, I remove an arbitrary number from an arbitrary group');
		var gr = 4 - 1 - (Random(4) - 1);
		while (group[gr] < 1) {
			gr = 4 - 1 - (Random(4) - 1);
		}
		var nr = Random(group[gr]);
		while (group[gr] < nr) {
			nr = Random(group[gr]);
		}
		group[gr] = group[gr] - nr; 
// alert('gr:'+gr+', nr:'+nr+', nnr:'+group[gr]);
	} else {
		row = SelectRow(X & group[0], X & group[1], X & group[2], X & group[3]); 
//alert('Not zero means you can\'t win: I must select the correct group. I calculate the -and- between '
//		+X+', the -exclusive or-, and each groups content-number ('+g1+','+g2+','+g3+','+g4
//		+'), to get ('+X&group[0]+','+X&group[1]+','+X&group[2]+','+X&group[3]
//		+') and then to pick the largest which is group '+(row+1)+' containing '+group[row]);
//alert('Then I must select the correct number to pick: I calculate the -exclusive or- '
//		+'between the other groups and substract the result from the contents of this group.');
		if (row == 0) {
			group[0] = group[0]
					- (group[0] - (group[1] ^ (group[2] ^ group[3])));
		} else if (row == 1) {
			group[1] = group[1]
					- (group[1] - (group[2] ^ (group[0] ^ group[3])));
		} else if (row == 2) {
			group[2] = group[2]
					- (group[2] - (group[3] ^ (group[1] ^ group[0])));
		} else if (row == 3) {
			group[3] = group[3]
					- (group[3] - (group[0] ^ (group[1] ^ group[2])));
		} else
			alert('selected wrong row');
		// alert('new :'+group[0]+','+group[1]+','+group[2]+','+group[3]+'');
	}
}// act

//--- returns a random integer :  0 < Random(n) < n ------------------------------------------
function Random(n) {
	today = new Date();
	if (n > 1) {
		m = today.getTime() % n;
		return m == 0 ? 1 : m;
	} else
		return 1;
} // Random

function SelectRow(a, b, c, d) { // alert('just in SelectRow('+a+','+b+','+c+','+d+')');
	A = a;
	N = 0;
	if (b > A) {
		A = b;
		N = 1;
	}
	if (c > A) {
		A = c;
		N = 2;
	}
	if (d > A)
		N = 3;
	return N;
} // SelectRow

