Skip to content

Commit

Permalink
Implemented Random AI
Browse files Browse the repository at this point in the history
  • Loading branch information
adithya321 committed Jun 23, 2016
1 parent 4e8b216 commit 6280579
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 24 deletions.
10 changes: 6 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
compileSdkVersion 24
buildToolsVersion "24.0.0"

defaultConfig {
applicationId "com.zduo.dotsandboxes"
minSdkVersion 14
targetSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
Expand All @@ -21,6 +21,8 @@ android {

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

compile 'com.android.support:appcompat-v7:24.0.0'

testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
}
28 changes: 14 additions & 14 deletions app/src/main/java/com/zduo/dotsandboxes/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.widget.ImageView;
import android.widget.TextView;

import com.zduo.dotsandboxes.ai.RandomAIPlayer;
import com.zduo.dotsandboxes.model.HumanPlayer;
import com.zduo.dotsandboxes.model.Player;
import com.zduo.dotsandboxes.view.GameView;
Expand Down Expand Up @@ -37,16 +38,11 @@ protected void onCreate(Bundle savedInstanceState) {
player2occupying = (TextView) findViewById(R.id.player2occupying);
currentPlayerPointer = (ImageView) findViewById(R.id.playerNowPointer);

new Thread() {
@Override
public void run() {
startGame();
}
}.start();
startGame();
}

private void startGame() {
players = new Player[]{new HumanPlayer("Player1"), new HumanPlayer("Player2")};
players = new Player[]{new HumanPlayer("Human"), new RandomAIPlayer("Computer")};
gameView.startGame(players);
updateState();
}
Expand All @@ -59,7 +55,7 @@ public void run() {
player1state.setText("Thinking");
player2state.setText("Waiting");
currentPlayerPointer.setImageResource(R.drawable.a1);
} else {
} else if (currentPlayer == players[1]) {
player2state.setText("Thinking");
player1state.setText("Waiting");
currentPlayerPointer.setImageResource(R.drawable.a2);
Expand Down Expand Up @@ -91,12 +87,16 @@ public void run() {
new AlertDialog.Builder(MainActivity.this)
.setTitle("Dots And Boxes")
.setMessage(winner.getName() + " Wins!")
.setPositiveButton("Restart",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
recreate();
}
}).show();
.setPositiveButton("Restart", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
recreate();
}
})
.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).show();
}
});
}
Expand Down
30 changes: 30 additions & 0 deletions app/src/main/java/com/zduo/dotsandboxes/ai/Box.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.zduo.dotsandboxes.ai;

public class Box {
boolean left;
boolean top;
boolean right;
boolean bottom;
boolean occupied;

Box(boolean l, boolean t, boolean r, boolean b) {
this.left = l;
this.top = t;
this.right = r;
this.bottom = b;

this.occupied = (l && t && r && b);
}

int occupiedLineCount() {
int count = 0;

if (this.left) count++;
if (this.right) count++;
if (this.top) count++;
if (this.bottom)
count++;

return count;
}
}
136 changes: 136 additions & 0 deletions app/src/main/java/com/zduo/dotsandboxes/ai/RandomAIPlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.zduo.dotsandboxes.ai;

import com.zduo.dotsandboxes.model.Direction;
import com.zduo.dotsandboxes.model.Line;
import com.zduo.dotsandboxes.model.Player;

import java.util.ArrayList;
import java.util.List;

public class RandomAIPlayer extends Player {

protected final ArrayList<Line> safeLines;
protected final ArrayList<Line> goodLines;
protected final ArrayList<Line> badLines;

public RandomAIPlayer(String name) {
super(name);

safeLines = new ArrayList<>();
goodLines = new ArrayList<>();
badLines = new ArrayList<>();
}

protected Line nextMove() {
if (goodLines.size() != 0) return getBestGoodLine();
if (safeLines.size() != 0) return getRandomSafeLine();

return getRandomBadLine();
}

public Line move() {
initialiseLines();
return nextMove();
}

private void initialiseLines() {
goodLines.clear();
badLines.clear();
safeLines.clear();

for (int i = 0; i < 6; i++) {
for (int j = 0; j < 5; j++) {
if (!isHorizontalLineOccupied(i, j)) {
if (i == 0) {
switch (getBox(i, j).occupiedLineCount()) {
case 3:
goodLines.add(new Line(Direction.HORIZONTAL, i, j));
break;
case 2:
badLines.add(new Line(Direction.HORIZONTAL, i, j));
break;
case 1:
case 0:
safeLines.add(new Line(Direction.HORIZONTAL, i, j));
}
} else if (i == 5) {
switch (getBox(i - 1, j).occupiedLineCount()) {
case 3:
goodLines.add(new Line(Direction.HORIZONTAL, i, j));
break;
case 2:
badLines.add(new Line(Direction.HORIZONTAL, i, j));
break;
case 1:
case 0:
safeLines.add(new Line(Direction.HORIZONTAL, i, j));
}
} else {
if (getBox(i, j).occupiedLineCount() == 3
|| getBox(i - 1, j).occupiedLineCount() == 3)
goodLines.add(new Line(Direction.HORIZONTAL, i, j));

if (getBox(i, j).occupiedLineCount() == 2
|| getBox(i - 1, j).occupiedLineCount() == 2)
badLines.add(new Line(Direction.HORIZONTAL, i, j));

if (getBox(i, j).occupiedLineCount() < 2
&& getBox(i - 1, j).occupiedLineCount() < 2)
safeLines.add(new Line(Direction.HORIZONTAL, i, j));
}
}

if (!isVerticalLineOccupied(j, i)) {
if (i == 0) {
if (getBox(j, i).occupiedLineCount() == 3)
goodLines.add(new Line(Direction.VERTICAL, j, i));
} else if (i == 5) {
if (getBox(j, i - 1).occupiedLineCount() == 3)
goodLines.add(new Line(Direction.VERTICAL, j, i));
} else {
if (getBox(j, i).occupiedLineCount() == 3
|| getBox(j, i - 1).occupiedLineCount() == 3)
goodLines.add(new Line(Direction.VERTICAL, j, i));

if (getBox(j, i).occupiedLineCount() == 2
|| getBox(j, i - 1).occupiedLineCount() == 2)
badLines.add(new Line(Direction.VERTICAL, j, i));

if (getBox(j, i).occupiedLineCount() < 2
&& getBox(j, i - 1).occupiedLineCount() < 2)
safeLines.add(new Line(Direction.VERTICAL, j, i));
}
}
}
}
}

protected Box getBox(int row, int column) {
return new Box(isVerticalLineOccupied(row, column), isHorizontalLineOccupied(row, column),
isVerticalLineOccupied(row, column + 1), isHorizontalLineOccupied(row + 1, column));
}

protected boolean isHorizontalLineOccupied(int row, int column) {
return getGame().isLineOccupied(Direction.HORIZONTAL, row, column);
}

protected boolean isVerticalLineOccupied(int row, int column) {
return getGame().isLineOccupied(Direction.VERTICAL, row, column);
}

protected Line getBestGoodLine() {
return goodLines.get(0);
}

protected Line getRandomSafeLine() {
return getRandomLine(safeLines);
}

protected Line getRandomBadLine() {
return getRandomLine(badLines);
}

private Line getRandomLine(List<Line> list) {
return list.get((int) (list.size() * Math.random()));
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/zduo/dotsandboxes/model/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public static int indexIn(Player player, Player[] players) {

public abstract Line move();

public Game getGame() {
return game;
}

public void addToGame(Game game) {
this.game = game;
}
Expand Down
18 changes: 12 additions & 6 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,24 @@
android:id="@+id/player1name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Player 1" />
android:text="Human"
android:textColor="@color/colorPrimary" />

<TextView
android:id="@+id/player1state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="Waiting" />
android:text="Waiting"
android:textColor="@color/colorPrimary" />

<TextView
android:id="@+id/player1occupying"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="Occupying 0" />
android:text="Occupying 0"
android:textColor="@color/colorPrimary" />
</LinearLayout>

<ImageView
Expand All @@ -62,23 +65,26 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:text="Player 2" />
android:text="Computer"
android:textColor="@color/colorAccent" />

<TextView
android:id="@+id/player2state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="end"
android:text="Waiting" />
android:text="Waiting"
android:textColor="@color/colorAccent" />

<TextView
android:id="@+id/player2occupying"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="end"
android:text="Occupying 0" />
android:text="Occupying 0"
android:textColor="@color/colorAccent" />
</LinearLayout>
</LinearLayout>

Expand Down

0 comments on commit 6280579

Please sign in to comment.