Skip to content

Commit

Permalink
Added contract check for remote and human player
Browse files Browse the repository at this point in the history
  • Loading branch information
ginowangsh4 committed Jun 9, 2018
1 parent cdf7448 commit 939e552
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 151 deletions.
2 changes: 1 addition & 1 deletion src/admin/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Admin {
private static DocumentBuilder db;
private static AdminSocket socket;
private static Parser parser;
private static IPlayer player;
private static APlayer player;

// TODO: make HPlayer work by launching App from CML
// CML arguments:
Expand Down
97 changes: 97 additions & 0 deletions src/main/APlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package tsuro;
import java.util.*;

public abstract class APlayer {

public State state;
public enum State { BORN, PLAY, DEAD }

/**
* Get the name of the APlayer
* @return name of the APlayer
*/
public abstract String getName() throws Exception;

/**
* Called to indicate a game is starting
* @param color the APlayer's color
* @param colors all of the APlayers' color, in the order that the game will be played
*/
public abstract void initialize(int color, List<Integer> colors) throws Exception;

/**
* Called at the first step in a game indicates where the APlayer wishes to place their token
* token must be placed along the edge in an unoccupied space
* @param b the current board state
* @return a token with the APlayer's color, its position [x,y] and index on tile
*/
public abstract Token placePawn(Board b) throws Exception;

/**
* Called to ask the APlayer to make a move
* @param b the current board state
* @param tilesLeft count of tiles that are not yet handed out to APlayers
* @return the tile the APlayer should place, suitably rotated
*/
public abstract Tile playTurn(Board b, List<Tile> hand, int tilesLeft) throws Exception;

/**
* Called to inform the APlayer of the final board state and which APlayers won the game.
* @param b the current board game
* @param colors the list of winner's colors
*/
public abstract void endGame(Board b, List<Integer> colors) throws Exception;

/**
* Check APlayer's state against sequential contract
* @param method string name of caller method
*/
public void checkState(String method) {
switch (method) {
case "initialize":
if (state != MPlayer.State.DEAD && state != null) {
throw new IllegalArgumentException("Sequential Contracts: Cannot initialize at this time");
}
state = MPlayer.State.BORN;
break;
case "place-pawn":
if (state != MPlayer.State.BORN) {
throw new IllegalArgumentException("Sequential Contracts: Cannot place pawn at this time");
}
state = MPlayer.State.PLAY;
break;
case "play-turn":
if (state != MPlayer.State.PLAY) {
throw new IllegalArgumentException("Sequential Contracts: Cannot play turn at this time");
}
break;
case "end-game":
if (state != MPlayer.State.PLAY) {
throw new IllegalArgumentException("Sequential Contracts: Cannot end game at this time");
}
state = MPlayer.State.DEAD;
break;
default:
throw new IllegalArgumentException("Sequential Contract: Invalid caller method");
}
}

/**
* Check a color and a list of colors against certain constraints
* @param color a color
* @param colors a list of colors
*/
public void validColorAndColors(int color, List<Integer> colors) {
if (!colors.contains(color)){
throw new IllegalArgumentException("Player is not authorized to be initialized");
}
if (color < 0 || color > 7) {
throw new IllegalArgumentException("Invalid player's color");
}
for (int c : colors) {
if (c < 0 || c > 7) {
throw new IllegalArgumentException("Player list contains invalid" + "player color");
}
}
}
}
44 changes: 21 additions & 23 deletions src/main/HPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

import org.w3c.dom.Document;
import tsuro.parser.Parser;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.List;

public class HPlayer implements IPlayer {
public class HPlayer extends APlayer {

private BufferedReader in;
private PrintWriter out;
Expand All @@ -21,7 +19,6 @@ public class HPlayer implements IPlayer {
private String name;
private int color;
private List<Integer> colors;
private boolean isWinner;

public HPlayer(String name) throws Exception {
ServerSocket socketListener = new ServerSocket(10000);
Expand All @@ -37,11 +34,14 @@ public String getName() {
}

public void initialize (int color, List<Integer> colors) {
checkState("initialize");
validColorAndColors(color, colors);
this.color = color;
this.colors = colors;
}

public Token placePawn(Board b) throws Exception {
checkState("place-pawn");
generateBoardImage(parser.boardParser.buildXML(b), -1, -1);
out.println("<place-pawn>");
// format: [side, index on side]
Expand All @@ -50,27 +50,29 @@ public Token placePawn(Board b) throws Exception {
}

public Tile playTurn(Board b, List<Tile> hand, int tilesLeft) throws Exception {
generateImages(b, hand);
checkState("play-turn");
generateBoardAndTileImages(b, hand);
out.println("<play-turn>");
// inform GUI about hand size
out.println(String.valueOf(hand.size()));
// format: [index of tile in hand, index of tile rotation]
String[] chosenTile = in.readLine().split(",");
return generateTile(hand, Integer.parseInt(chosenTile[0]), Integer.parseInt(chosenTile[1]));
return getTile(hand, Integer.parseInt(chosenTile[0]), Integer.parseInt(chosenTile[1]));
}

public void endGame(Board b, List<Integer> colors) throws Exception {
checkState("end-game");
generateBoardImage(parser.boardParser.buildXML(b), -1, -1);
out.println("<end-game>");
String winnerList = "";
// inform GUI about winners list
StringBuilder winnerList = new StringBuilder();
for (int i = 0; i < colors.size(); i++) {
String colorString = Token.colorMap.get(colors.get(i));
winnerList = winnerList + colorString;
winnerList.append(Token.colorMap.get(colors.get(i)));
if (i != colors.size() - 1) {
winnerList += ", ";
winnerList.append(", ");
}
}
out.println(winnerList);
out.println(winnerList.toString());
}

private Token findMyToken(Board b) {
Expand Down Expand Up @@ -113,15 +115,15 @@ public static Token generateTokenFromSideAndIndex(int colorIndex, String side, i
return new Token(colorIndex, pos, indexOnTile);
}

private Tile generateTile(List<Tile> hand, int handIndex, int rotationIndex) {
private Tile getTile(List<Tile> hand, int handIndex, int rotationIndex) {
Tile move = hand.get(handIndex).copyTile();
for (int i = 0; i < rotationIndex; i++) {
move.rotateTile();
}
return move;
}

private void generateImages(Board b, List<Tile> hand) throws Exception {
private void generateBoardAndTileImages(Board b, List<Tile> hand) throws Exception {
Document boardXML = parser.boardParser.buildXML(b);
generateBoardImage(boardXML, -1, -1);
Token token = findMyToken(b);
Expand Down Expand Up @@ -150,19 +152,15 @@ private void generateBoardImage(Document doc, int tileIndex, int rotationIndex)
if (tileIndex == -1 && rotationIndex == -1) {
command = "./visualize -b -i image/board/board.png";
}
String line;
Process p = Runtime.getRuntime().exec(command);
PrintWriter out = new PrintWriter(p.getOutputStream(), true);
out.println(parser.documentToString(doc));
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
processCommand(doc, command);
}

private void generateTileImage(Document doc, int tileIndex) throws Exception {
String command = "./visualize -t -i image/hand/" + tileIndex + ".png";
processCommand(doc, "./visualize -t -i image/hand/" + tileIndex + ".png");

}

private void processCommand(Document doc, String command) throws Exception {
String line;
Process p = Runtime.getRuntime().exec(command);
PrintWriter out = new PrintWriter(p.getOutputStream(), true);
Expand Down
40 changes: 0 additions & 40 deletions src/main/IPlayer.java

This file was deleted.

63 changes: 1 addition & 62 deletions src/main/MPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
import java.util.List;
import java.util.Random;

public class MPlayer implements IPlayer {
public class MPlayer extends APlayer {

private String name;
private int color;
private List<Integer> colors;
private boolean isWinner;

public Strategy strategy;
public enum Strategy { R, MS, LS }
public State state;
public enum State { BORN, PLAY, DEAD }

public MPlayer(Strategy strategy, String name) {
this.name = name;
Expand Down Expand Up @@ -87,64 +84,6 @@ public Tile playTurn(Board b, List<Tile> hand, int tilesLeft) throws Exception {

public void endGame(Board b, List<Integer> colors) {
checkState("end-game");
this.colors = colors;
if (colors.contains(this.color)) {
isWinner = true;
}
isWinner = false;
}

/**
* Check IPlayer's state against sequential contract
* @param method string name of caller method
*/
private void checkState(String method) {
switch (method) {
case "initialize":
if (state != State.DEAD && state != null) {
throw new IllegalArgumentException("Sequential Contracts: Cannot initialize at this time");
}
state = State.BORN;
break;
case "place-pawn":
if (state != State.BORN) {
throw new IllegalArgumentException("Sequential Contracts: Cannot place pawn at this time");
}
state = State.PLAY;
break;
case "play-turn":
if (state != State.PLAY) {
throw new IllegalArgumentException("Sequential Contracts: Cannot play turn at this time");
}
break;
case "end-game":
if (state != State.PLAY) {
throw new IllegalArgumentException("Sequential Contracts: Cannot end game at this time");
}
state = State.DEAD;
break;
default:
throw new IllegalArgumentException("Sequential Contract: Invalid caller method");
}
}

/**
* Check a color and a list of colors against certain constraints
* @param color a color
* @param colors a list of colors
*/
private void validColorAndColors(int color, List<Integer> colors) {
if (!colors.contains(color)){
throw new IllegalArgumentException("Player is not authorized to be initialized");
}
if (color < 0 || color > 7) {
throw new IllegalArgumentException("Invalid player's color");
}
for (int c : colors) {
if (c < 0 || c > 7) {
throw new IllegalArgumentException("Player list contains invalid" + "player color");
}
}
}

/**
Expand Down
Loading

0 comments on commit 939e552

Please sign in to comment.