545 lines
16 KiB
Java
Executable file
545 lines
16 KiB
Java
Executable file
// Alex Huddleston and Brandon Jackson
|
|
// Breakthrough Client in Java
|
|
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.net.ServerSocket;
|
|
import java.net.Socket;
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStreamReader;
|
|
import java.util.Scanner;
|
|
import java.io.DataInputStream;
|
|
import java.util.Arrays;
|
|
import javax.swing.*;
|
|
import javax.*;
|
|
import java.awt.*;
|
|
import java.awt.geom.*;
|
|
import java.awt.event.*;
|
|
import java.awt.image.BufferedImage;
|
|
import javax.swing.border.*;
|
|
import java.net.URL;
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.image.*;
|
|
import java.io.File;
|
|
import java.io.InputStream;
|
|
//import javax.swing.text.html.parser.ParserDelegator;
|
|
|
|
public class Client {
|
|
|
|
private final JPanel gui = new JPanel(new BorderLayout(3, 3));
|
|
private JButton[][] boardSquares = new JButton[8][8];
|
|
private Image[] pieceImages = new Image[2];
|
|
private JPanel boardPanel;
|
|
private static final String Columns = "ABCDEFGH";
|
|
public static final int BLACK = 0, WHITE = 1;
|
|
public static String boardoutput = "";
|
|
public String oldBoard = "";
|
|
public static String undoString = "";
|
|
public static char myTurn = 'O';
|
|
|
|
public Client() {
|
|
initializeGui();
|
|
}
|
|
|
|
public final void initializeGui() {
|
|
createImages();
|
|
|
|
gui.setBorder(new EmptyBorder(5,5,5,5));
|
|
|
|
boardPanel = new JPanel(new GridLayout(0, 9)) {
|
|
|
|
/**
|
|
* Override the preferred size to return the largest it can, in
|
|
* a square shape. Must (must, must) be added to a GridBagLayout
|
|
* as the only component (it uses the parent as a guide to size)
|
|
* with no GridBagConstaint (so it is centered).
|
|
*/
|
|
@Override
|
|
public final Dimension getPreferredSize() {
|
|
Dimension d = super.getPreferredSize();
|
|
Dimension prefSize = null;
|
|
Component c = getParent();
|
|
if (c == null) {
|
|
prefSize = new Dimension(
|
|
(int)d.getWidth(),(int)d.getHeight());
|
|
} else if (c!=null &&
|
|
c.getWidth()>d.getWidth() &&
|
|
c.getHeight()>d.getHeight()) {
|
|
prefSize = c.getSize();
|
|
} else {
|
|
prefSize = d;
|
|
}
|
|
int w = (int) prefSize.getWidth();
|
|
int h = (int) prefSize.getHeight();
|
|
// the smaller of the two sizes
|
|
int s = (w>h ? h : w);
|
|
return new Dimension(s,s);
|
|
}
|
|
};
|
|
boardPanel.setBorder(new CompoundBorder(
|
|
new EmptyBorder(8,8,8,8),
|
|
new LineBorder(Color.BLACK)
|
|
));
|
|
// Set BG.
|
|
Color background = new Color(100,100,100);
|
|
Color boardbg = new Color(250, 200, 100);
|
|
boardPanel.setBackground(background);
|
|
JPanel boardConstrain = new JPanel(new GridBagLayout());
|
|
boardConstrain.setBackground(background);
|
|
boardConstrain.add(boardPanel);
|
|
gui.add(boardConstrain);
|
|
|
|
Insets buttonMargin = new Insets(0,0,0,0);
|
|
for(int r = 0; r < boardSquares.length; ++r) {
|
|
for(int c = 0; c < boardSquares.length; ++c) {
|
|
final int selectrow = r;
|
|
final int selectcol = c;
|
|
Action selectPiece = new AbstractAction("") {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
sendLocation(selectrow, selectcol);
|
|
}
|
|
};
|
|
JButton b = new JButton();
|
|
b.setMargin(buttonMargin);
|
|
b.setAction(selectPiece);
|
|
|
|
ImageIcon icon = new ImageIcon( new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
|
|
b.setIcon(icon);
|
|
b.setBackground(boardbg);
|
|
boardSquares[r][c] = b;
|
|
}
|
|
}
|
|
|
|
// fill the board.
|
|
Action undoMove = new AbstractAction("") {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
undoMoveSend();
|
|
}
|
|
};
|
|
ImageIcon icon = new ImageIcon( new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
|
|
JButton undo = new JButton("UNDO", icon);
|
|
undo.setMargin(buttonMargin);
|
|
undo.setAction(undoMove);
|
|
undo.setBackground(new Color(150, 150, 150));
|
|
boardPanel.add(undo);
|
|
// fill the top row
|
|
for(int c = 0; c < 8; c++) {
|
|
boardPanel.add(new JLabel(Columns.substring(c, c + 1), SwingConstants.CENTER));
|
|
}
|
|
// fill everything else
|
|
for(int r = 0; r < 8; ++r) {
|
|
for(int c = 0; c < 8; c++) {
|
|
switch(c) {
|
|
case 0: boardPanel.add(new JLabel("" + (9 - (r + 1)), SwingConstants.CENTER));
|
|
|
|
default: boardPanel.add(boardSquares[r][c]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public final JComponent getGui() {
|
|
return gui;
|
|
}
|
|
|
|
private final void createImages() {
|
|
try {
|
|
//URL url1 = new URL("http://www.iconsdb.com/icons/preview/black/circle-xxl.png");
|
|
BufferedImage bi = ImageIO.read(new File("Resources/black_circle.png"));
|
|
Image img = bi.getScaledInstance(64, 64, BufferedImage.SCALE_FAST);
|
|
pieceImages[0] = img;
|
|
|
|
//URL url2 = new URL("http://www.iconsdb.com/icons/preview/white/circle-xxl.png");
|
|
bi = ImageIO.read(new File("Resources/white_circle.png"));
|
|
img = bi.getScaledInstance(64, 64, BufferedImage.SCALE_FAST);
|
|
pieceImages[1] = img;
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
System.exit(1);
|
|
}
|
|
}
|
|
|
|
public String TrimBoard(String board) {
|
|
String output = "";
|
|
for(int i = 0; i < board.length(); ++i) {
|
|
if((output.length() != 64) && board.charAt(i) == 'X') {
|
|
output += board.charAt(i);
|
|
}
|
|
|
|
else if((output.length() != 64) && board.charAt(i) == '_') {
|
|
output += board.charAt(i);
|
|
}
|
|
|
|
else if((output.length() != 64) && board.charAt(i) == 'O') {
|
|
output += board.charAt(i);
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
|
|
public final void updateBoard(String board) {
|
|
board = TrimBoard(board);
|
|
System.out.println(board);
|
|
int count = 0;
|
|
ImageIcon icon = new ImageIcon( new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
|
|
if(oldBoard.equals("")) {
|
|
for(int r = 0; r < 8; ++r) {
|
|
for(int c = 0; c < 8; c++) {
|
|
if(board.charAt(count) == 'X') {
|
|
boardSquares[r][c].setIcon(new ImageIcon(pieceImages[0]));
|
|
}
|
|
else if(board.charAt(count) == 'O') {
|
|
boardSquares[r][c].setIcon(new ImageIcon(pieceImages[1]));
|
|
}
|
|
else {
|
|
boardSquares[r][c].setIcon(icon);
|
|
}
|
|
count++;
|
|
}
|
|
}
|
|
count = 0;
|
|
}
|
|
else {
|
|
for(int r = 0; r < 8; ++r) {
|
|
for(int c = 0; c < 8; c++) {
|
|
if(board.charAt(count) == 'X' && oldBoard.charAt(count) != 'X') {
|
|
boardSquares[r][c].setIcon(new ImageIcon(pieceImages[0]));
|
|
}
|
|
else if(board.charAt(count) == 'O' && oldBoard.charAt(count) != 'O') {
|
|
boardSquares[r][c].setIcon(new ImageIcon(pieceImages[1]));
|
|
}
|
|
else if(board.charAt(count) == '_' && oldBoard.charAt(count) != '_') {
|
|
boardSquares[r][c].setIcon(icon);
|
|
}
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
oldBoard = board;
|
|
}
|
|
|
|
public final void undoMoveSend() {
|
|
undoString = "UNDO";
|
|
}
|
|
|
|
public void sendLocation(int r, int c) {
|
|
//debugging.
|
|
System.out.println("row: " + r + " col: " + c);
|
|
boardoutput += "" + r + "" + c;
|
|
}
|
|
|
|
public static String parseOutput(String move) {
|
|
String output = "";
|
|
int tempa = move.charAt(0) - '0';
|
|
int tempb = move.charAt(1) - '0';
|
|
int tempc = move.charAt(2) - '0';
|
|
int tempd = move.charAt(3) - '0';
|
|
|
|
if((myTurn == 'O') && (tempa == (tempc + 1))) {
|
|
//cout << "\nTest\n";
|
|
if(tempb == tempd) {
|
|
output = ((char)('A' + tempb)) + "" + (8 - tempa) + " FWD";
|
|
}
|
|
else if(tempb == (tempd + 1)) {
|
|
output = ((char)('A' + tempb)) + "" + (8 - tempa) + " LEFT";
|
|
}
|
|
else if(tempb == (tempd - 1)) {
|
|
output = ((char)('A' + tempb)) + "" + (8 - tempa) + " RIGHT";
|
|
}
|
|
}
|
|
else if((myTurn == 'X') && (tempa == (tempc - 1))){
|
|
//cout << "\nTest\n";
|
|
if(tempb == tempd) {
|
|
output = ((char)('A' + tempb)) + "" + (8 - tempa) + " FWD";
|
|
}
|
|
else if(tempb == (tempd + 1)) {
|
|
output = ((char)('A' + tempb)) + "" + (8 - tempa) + " LEFT";
|
|
}
|
|
else if(tempb == (tempd - 1)) {
|
|
output = ((char)('A' + tempb)) + "" + (8 - tempa) + " RIGHT";
|
|
}
|
|
}
|
|
else {
|
|
return "Invalid";
|
|
}
|
|
//Debugging
|
|
System.out.println("Output: " + output);
|
|
return output;
|
|
}
|
|
|
|
public static void main (String[] args) throws InterruptedException {
|
|
Scanner keyboard = new Scanner(System.in);
|
|
String hostname = args[0];
|
|
int portnum = Integer.parseInt(args[1]);
|
|
|
|
try {
|
|
Socket echoSocket = new Socket(hostname, portnum);
|
|
PrintWriter output = new PrintWriter(echoSocket.getOutputStream(), true);
|
|
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
|
|
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
|
|
|
|
String userInput = "test";
|
|
char[] b = new char[256];
|
|
in.read(b, 0, 256);
|
|
|
|
String temp = String.valueOf(b).trim();
|
|
String g = "GAME OVER";
|
|
char[] go = new char[9];
|
|
for(int x = 0; x < go.length; ++x) {
|
|
go[x] = g.charAt(x);
|
|
}
|
|
|
|
boolean end = false;
|
|
int c = 0;
|
|
|
|
Client window = new Client();
|
|
|
|
JFrame frame = new JFrame("Breakthrough");
|
|
frame.add(window.getGui());
|
|
|
|
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
frame.setLocationByPlatform(true);
|
|
frame.pack();
|
|
frame.setMinimumSize(frame.getSize());
|
|
frame.setVisible(true);
|
|
//userInput = stdIn.readLine();
|
|
int gameMode = 0;
|
|
String diff = "?";
|
|
if(!temp.equals("skip")) {
|
|
userInput = JOptionPane.showInputDialog(frame, temp);
|
|
//gameMode = Integer.parseInt(userInput);
|
|
while(!userInput.equals("1") && !userInput.equals("2") && !userInput.equals("3")) {
|
|
userInput = JOptionPane.showInputDialog(frame, temp);
|
|
output.println(userInput);
|
|
}
|
|
gameMode = Integer.parseInt(userInput);
|
|
output.println(userInput);
|
|
|
|
if(gameMode != 3) {
|
|
in.read(b, 0, 256);
|
|
temp = String.valueOf(b).trim();
|
|
while(!diff.equals("1") && !diff.equals("2") && !diff.equals("3")) {
|
|
diff = JOptionPane.showInputDialog(frame, temp);//diff = stdIn.readLine();
|
|
//diff = diff.toUpperCase();
|
|
if(!diff.equals("1") && !diff.equals("2") && !diff.equals("3")) {
|
|
JOptionPane.showMessageDialog(null, diff + "\nInvalid difficulty.\n" + temp);
|
|
}
|
|
}
|
|
if(diff.equals("1")) {
|
|
userInput = "EASY";
|
|
}
|
|
else if(diff.equals("2")) {
|
|
userInput = "MEDIUM";
|
|
}
|
|
else if(diff.equals("3")) {
|
|
userInput = "HARD";
|
|
}
|
|
output.println(userInput);
|
|
}
|
|
}
|
|
else {
|
|
gameMode = 3;
|
|
myTurn = 'X';
|
|
}
|
|
String out = "";
|
|
if(gameMode == 3)
|
|
{
|
|
in.read(b, 0, 256);
|
|
temp = String.valueOf(b).trim();
|
|
userInput = JOptionPane.showInputDialog(frame, temp);
|
|
//gameMode = Integer.parseInt(userInput);
|
|
while(!userInput.equals("1") && !userInput.equals("2")) {
|
|
userInput = JOptionPane.showInputDialog(frame, temp);
|
|
output.println(userInput);
|
|
}
|
|
gameMode = Integer.parseInt(userInput);
|
|
output.println(userInput);
|
|
|
|
if(gameMode == 2) {
|
|
in.read(b, 0, 256);
|
|
temp = String.valueOf(b).trim();
|
|
userInput = JOptionPane.showInputDialog(frame, temp);
|
|
diff = userInput;
|
|
while(!diff.equals("1") && !diff.equals("2") && !diff.equals("3")) {
|
|
diff = JOptionPane.showInputDialog(frame, temp);//diff = stdIn.readLine();
|
|
//diff = diff.toUpperCase();
|
|
if(!diff.equals("1") && !diff.equals("2") && !diff.equals("3")) {
|
|
JOptionPane.showMessageDialog(null, diff + "\nInvalid difficulty.\n" + temp);
|
|
}
|
|
}
|
|
if(diff.equals("1")) {
|
|
userInput = "EASY";
|
|
}
|
|
else if(diff.equals("2")) {
|
|
userInput = "MEDIUM";
|
|
}
|
|
else if(diff.equals("3")) {
|
|
userInput = "HARD";
|
|
}
|
|
output.println(userInput);
|
|
}
|
|
|
|
while(!end) {
|
|
char[] buffer = new char[256];
|
|
if(gameMode == 1) {
|
|
in.read(buffer, 0, 256);
|
|
for(int i = 0; i < buffer.length; ++i) {
|
|
if(Arrays.equals(Arrays.copyOfRange(buffer, i, i+9), go)) {
|
|
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
|
|
JOptionPane.showMessageDialog(null, "\nGAME OVER\n");
|
|
end = true;
|
|
}
|
|
}
|
|
System.out.println(String.valueOf(buffer).trim());
|
|
window.updateBoard(String.valueOf(buffer).trim());
|
|
while(!end && boardoutput.length() < 4) {
|
|
if(in.ready()) {
|
|
in.read(buffer, 0, 256);
|
|
for(int i = 0; i < buffer.length; ++i) {
|
|
if(Arrays.equals(Arrays.copyOfRange(buffer, i, i+9), go)) {
|
|
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
|
|
JOptionPane.showMessageDialog(null, "\nGAME OVER\n");
|
|
end = true;
|
|
}
|
|
}
|
|
System.out.println(String.valueOf(buffer).trim());
|
|
window.updateBoard(String.valueOf(buffer).trim());
|
|
}
|
|
String tempstring;
|
|
Thread.sleep(1);
|
|
if(!undoString.equals("")) {
|
|
System.out.println(undoString);
|
|
output.println(undoString);
|
|
output.flush();
|
|
undoString = "";
|
|
}
|
|
if(boardoutput.length() == 4) {
|
|
out = parseOutput(boardoutput);
|
|
if(out == "Invalid") {
|
|
out = "";
|
|
boardoutput = "";
|
|
System.out.println("Invalid move.");
|
|
}
|
|
}
|
|
}
|
|
//System.out.println(String.valueOf(buffer).trim());
|
|
System.out.println(out);
|
|
output.println(out);
|
|
output.flush();
|
|
boardoutput = "";
|
|
}
|
|
else {
|
|
if(in.ready()) {
|
|
in.read(buffer, 0, 256);
|
|
for(int i = 0; i < buffer.length; ++i) {
|
|
if(Arrays.equals(Arrays.copyOfRange(buffer, i, i+9), go)) {
|
|
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
|
|
JOptionPane.showMessageDialog(null, "\nGAME OVER\n");
|
|
end = true;
|
|
}
|
|
}
|
|
System.out.println(String.valueOf(buffer).trim());
|
|
window.updateBoard(String.valueOf(buffer).trim());
|
|
}
|
|
}
|
|
}
|
|
output.close();
|
|
in.close();
|
|
stdIn.close();
|
|
echoSocket.close();
|
|
}
|
|
else if(gameMode == 1)
|
|
{
|
|
while(!end) {
|
|
char[] buffer = new char[256];
|
|
in.read(buffer, 0, 256);
|
|
for(int i = 0; i < buffer.length; ++i) {
|
|
if(Arrays.equals(Arrays.copyOfRange(buffer, i, i+9), go)) {
|
|
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
|
|
JOptionPane.showMessageDialog(null, "\nGAME OVER\n");
|
|
end = true;
|
|
}
|
|
}
|
|
System.out.println(String.valueOf(buffer).trim());
|
|
window.updateBoard(String.valueOf(buffer).trim());
|
|
while(!end && boardoutput.length() < 4) {
|
|
String tempstring;
|
|
Thread.sleep(100);
|
|
if(!undoString.equals("")) {
|
|
System.out.println(undoString);
|
|
output.println(undoString);
|
|
output.flush();
|
|
undoString = "";
|
|
}
|
|
if(boardoutput.length() == 4) {
|
|
out = parseOutput(boardoutput);
|
|
if(out == "Invalid") {
|
|
out = "";
|
|
boardoutput = "";
|
|
System.out.println("Invalid move.");
|
|
}
|
|
}
|
|
}
|
|
System.out.println(String.valueOf(buffer).trim());
|
|
System.out.println(out);
|
|
output.println(out);
|
|
output.flush();
|
|
boardoutput = "";
|
|
}
|
|
output.close();
|
|
in.close();
|
|
stdIn.close();
|
|
echoSocket.close();
|
|
}
|
|
else if(gameMode == 2)
|
|
{
|
|
while(!end) {
|
|
char[] buffer = new char[256];
|
|
in.read(buffer, 0, 256);
|
|
for(int i = 0; i < buffer.length; ++i) {
|
|
if(Arrays.equals(Arrays.copyOfRange(buffer, i, i+9), go)) {
|
|
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
|
|
JOptionPane.showMessageDialog(null, "\nGAME OVER\n");
|
|
end = true;
|
|
}
|
|
}
|
|
System.out.println(String.valueOf(buffer).trim());
|
|
window.updateBoard(String.valueOf(buffer).trim());
|
|
/*
|
|
while(!end && boardoutput.length() < 4) {
|
|
Thread.sleep(100);
|
|
if(!undoString.equals("")) {
|
|
System.out.println(undoString);
|
|
//output.println(undoString);
|
|
//output.flush();
|
|
undoString = "";
|
|
}
|
|
if(boardoutput.length() == 4) {
|
|
out = parseOutput(boardoutput);
|
|
if(out == "Invalid") {
|
|
out = "";
|
|
boardoutput = "";
|
|
System.out.println("Invalid move.");
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
System.out.println(out);
|
|
//output.println(out);
|
|
//output.flush();
|
|
boardoutput = "";
|
|
}
|
|
output.close();
|
|
in.close();
|
|
stdIn.close();
|
|
echoSocket.close();
|
|
}
|
|
}
|
|
catch (IOException e){
|
|
System.err.println("IOException: " + e.getMessage());
|
|
}
|
|
}
|
|
}
|