Click here to Skip to main content
15,894,410 members
Articles / Mobile Apps / Android

Nim Challenge

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
26 Jul 2012Apache7 min read 33.6K   1.2K   15  
Nim game for Android devices
package gr.sullenart.games.nimchallenge.gameengine;

import java.util.Random;
import java.util.Vector;

//import android.util.Log;

public class NimEngine {

	private static Random random = new Random();

	private int boardSize;

	private boolean lastWins;
	
	public NimEngine(int boardSize, boolean lastWins) {
		this.boardSize = boardSize;
		this.lastWins = lastWins;
	}

	private boolean gameFinished = false;

	public boolean isGameFinished() {
		return gameFinished;
	}

	/*private Vector<int[]> getGameRows(int [] boardTable) {
		Vector<int[]> rows = new Vector<int[]>();

		boolean isPegFound;
		int start = 0, stop = 0;
		for (int r=0; r<boardSize; r++) {
			isPegFound = false;
			for (int c=0; c<boardSize; c++) {
				if (boardTable[r*boardSize + c] != 0 && !isPegFound) {
					isPegFound = true;
					start = r*boardSize + c;
					stop = start;
				}
				else if (boardTable[r*boardSize + c] != 0) {
					stop = r*boardSize + c;
				}
				else if (isPegFound &&
							(boardTable[r*boardSize + c] == 0 || c == (boardSize - 1)))
					{
					isPegFound = false;
					rows.add(new int [] {start, stop});
				}
			}
		}

		return rows;
	}*/

	private boolean evaluate(int [] boardTable)
	{
	    int [] sets = new int[boardSize];
	    int row, column, count;

	    for(int i=0; i<boardSize; i++) {
	    	sets[i] = 0;
	    }

	    for(row=0;row<boardSize;row++) {
	        count = 0;
	        for(column=0;column<boardSize;column++) {
	            if (boardTable[row*boardSize+column]==1) {
	                count++;
	            }
	            else if (boardTable[row*boardSize+column]==0 && count > 0) {
	                sets[count-1]++;
	                count = 0;
	            }
	        }
	        if (count > 0) {
	            sets[count-1]++;
	        }
	    }

	    if (!lastWins) {
	    	boolean onlyOnes = true;
		    for(int i=1;i<boardSize;i++) {
		        if (sets[i] > 0) {
		        	onlyOnes = false;
		        	break;
		        }
		    }
		    if (onlyOnes) {
		    	return sets[0] % 2 == 1;
		    }
	    }
	    
	    int result = 0;
	    for(int i=0;i<boardSize;i++) {
	        if (sets[i]%2!=0) {
	            result^=(i+1);
	        }
	    }

	    return result == 0;
	}


	private int getRemainingPegsCount(int [] boardTable)
	{
	    int count = 0;
		for(int i=0;i<boardSize*boardSize;i++) {
	        if (boardTable[i]!=0)
	            count++;
	    }
	    return count;
	}


	public Vector<Integer> getMove(int [] boardTable) {
		gameFinished = false;

		int remainingPegsCount = getRemainingPegsCount(boardTable);
		if (remainingPegsCount == 0) {
			gameFinished = true;
			return null;
		}
		Vector<int [] > moves = new Vector<int[]>();


		int [] tempBoard = new int [boardTable.length];
	    for(int i=0;i<boardSize*boardSize;i++) {
	        tempBoard[i] = boardTable[i];
	    }

	    int count = 0;
	    int moveCount = 0;
	    int selectedMove = 0;
	    int  winningMoveCount = 0;
	    for(int row=0;row<boardSize;row++) {
	        count = 0;
	        for(int column=0;column<boardSize;column++) {
	            if (boardTable[row*boardSize+column]==1) {
	                count++;
	            }
	            else {
	                count=0;
	            }

	            if (count > 0) {
	                moveCount++;
	                int [] move = new int[count];
	                int j = count - 1;
	                for(int i=row*boardSize+column; i>(row*boardSize+column-count);i--) {
	                    tempBoard[i] = 0;
	                    move[j--] = i;
	                }
	                moves.add(move);
	                if (evaluate(tempBoard)) {
	                    if (selectedMove == 0) {
	                        selectedMove = moveCount;
	                    }
	                    else {
	                        if (Math.random()>0.5)
	                        {
	                            selectedMove = moveCount;
	                        }
	                    }
	                    winningMoveCount++;
	                }
	                for(int i=row*boardSize+column;i>row*boardSize+column-count;i--) {
	                    tempBoard[i] = 1;
	                }
	            }
	        }
	    }

	    if (winningMoveCount == 0) {
	        selectedMove = random.nextInt(moveCount) + 1;
	    }

	    Vector<Integer> result = new Vector<Integer>();
	    for(int i: moves.get(selectedMove-1)) {
	    	result.add(i);
	    	boardTable[i] = 0;
	    }
	    gameFinished = remainingPegsCount == result.size();
		return result;
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Software Developer (Senior) Self employed
Greece Greece
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions