diff --git a/Board.cpp b/Board.cpp new file mode 100644 index 0000000..6750ab2 --- /dev/null +++ b/Board.cpp @@ -0,0 +1,554 @@ +#include +#include +#include "Board.h" + +using namespace std; + +Board::Board() { + Piece* temp; + bool valid = false; + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < 8; ++j) { + temp = new Piece(i, j, 'X'); + xpieces.push_back(temp); + pieces.push_back(temp); + } + } + + for (int i = 6; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + temp = new Piece(i, j, 'O'); + opieces.push_back(temp); + pieces.push_back(temp); + } + } +} + +Board::Board(const Board& b) { + vector xp = b.getXPieces(); + vector op = b.getOPieces(); + Piece* temp; + //bool valid = false; + char tempturn = b.getTurnPls(); + turn = tempturn; + + for (int i = 0; i < xp.size(); ++i) { + temp = new Piece(xp[i]->getX(), xp[i]->getY(), 'X'); + xpieces.push_back(temp); + pieces.push_back(temp); + } + + for (int i = 0; i < op.size(); ++i) { + temp = new Piece(op[i]->getX(), op[i]->getY(), 'O'); + opieces.push_back(temp); + pieces.push_back(temp); + } +} + +//make this efficient! +bool Board::isPiece(int r, int c){ + for (int i = 0; i < pieces.size(); ++i){ + if (pieces[i]->getX() == r && pieces[i]->getY() == c){ + return true; + } + } + + return false; +} + +//make this efficient! +Piece* Board::getPiece(int r, int c){ + for (int i = 0; i < pieces.size(); ++i){ + if (pieces[i]->getX() == r && pieces[i]->getY() == c){ + return pieces[i]; + } + } + + return new Piece(); +} + +void Board::isTaken(int r, int c) { + for (int i = 0; i < pieces.size(); ++i){ + if (pieces[i]->getX() == r && pieces[i]->getY() == c){ + if(pieces[i]->getType() == 'O') { + for(int x = 0; x < opieces.size(); ++x) { + if (opieces[x]->getX() == r && opieces[x]->getY() == c) { + opieces.erase(opieces.begin() + x); + } + } + } + else { + for(int x = 0; x < xpieces.size(); ++x) { + if (xpieces[x]->getX() == r && xpieces[x]->getY() == c) { + xpieces.erase(xpieces.begin() + x); + } + } + } + pieces.erase(pieces.begin() + i); + break; + } + } +} + +moves Board::parse(string input){ + input = myToUpper(input); + + int temp1; + int temp2; + string temp3; + + temp2 = input[0] - 'A'; + temp1 = input[1] - '0'; + + if (input[3] == 'L') + { + temp3 = "LEFT"; + } + + else if (input[3] == 'R') + { + temp3 = "RIGHT"; + } + + else + { + temp3 = "FWD"; + } + + moves output(temp1, temp2, temp3); + + return output; +} + +bool Board::isGameOver(){ + for (int i = 0; i < xpieces.size(); ++i){ + if (xpieces[i]->getX() == 7){ + return true; + } + } + + for (int i = 0; i < opieces.size(); ++i){ + if (opieces[i]->getX() == 0){ + return true; + } + } + + return false; +} + +string Board::whoWon(){ + for (int i = 0; i < xpieces.size(); ++i){ + if (xpieces[i]->getX() == 7){ + return "Player X wins!"; + } + } + + for (int i = 0; i < opieces.size(); ++i){ + if (opieces[i]->getX() == 0){ + return "Player O wins!"; + } + } + + return "ERROR: function whoWon() called incorrectly."; +} + +void Board::changeTurns(){ + if (turn == 'O') turn = 'X'; + else turn = 'O'; +} + +void Board::displayBoard(){ + cout << "; A B C D E F G H"<getType() == 'X') + cout << "|" << "X"; + else + cout << "|" << "O"; + else + cout << "|" << "_"; + } + + cout<<"|\n"; + } + + cout<<'\n'<getType() == 'X') + output += "|X"; + else + output += "|O"; + else + output += "|_"; + } + + output += "|\n"; + } + + output += "\n\nturn: "; + output += turn; + output += "\n"; + + return output; +} + +int Board::charToIntColumn(char input){ + int kolumn; + + switch (input) + { + case 'A': kolumn = 0; break; + case 'B': kolumn = 1; break; + case 'C': kolumn = 2; break; + case 'D': kolumn = 3; break; + case 'E': kolumn = 4; break; + case 'F': kolumn = 5; break; + case 'G': kolumn = 6; break; + case 'H': kolumn = 7; break; + } + + return kolumn; +} + +char Board::intToCharColumn(int input){ + char kolumn; + + switch (input) + { + case 1: kolumn = 'A'; break; + case 2: kolumn = 'B'; break; + case 3: kolumn = 'C'; break; + case 4: kolumn = 'D'; break; + case 5: kolumn = 'E'; break; + case 6: kolumn = 'F'; break; + case 7: kolumn = 'G'; break; + case 8: kolumn = 'H'; break; + } + + return kolumn; +} + +void Board::move(string inputMove){ + moves m = parse(inputMove); + //cout << "MOVE: " << m.row << " " << m.column << " " << m.moveType << "\n\n"; + move(m); +} + +Board Board::move(moves m){ + int row = 8 - (m.row); + int column = m.column; + + //cout << "INSIDE MOVE: " << row << " " << column << " " << m.moveType << "\n\n"; + + if (row > 8 || row < 0 || column > 8 || column < 0) { + cout<<"ERROR: index out of bound."<getX() << piece->getY() << "\n\n"; + if (piece->getType() != turn) { + cout<<"ERROR: attempting to move the wrong side's piece.\n"; + } + + else { + if(isThisMovePossible(row, column, m.moveType)) + { + if (m.moveType == "FWD") { + piece->moveFwd(); + } + + else if (m.moveType == "LEFT") { + //add error checking + if(piece->getType() == 'O') { + row--; + column--; + } + else { + row++; + column--; + } + if(isPiece(row, column)) { + if(getPiece(row, column)->getType() != piece->getType()) { + isTaken(row, column); + piece->moveLeft(); + } + } + else { + piece->moveLeft(); + } + } + + else if (m.moveType == "RIGHT") { + //add error checking + //cout << "TESTING??\n\n"; + if(piece->getType() == 'O') { + row--; + column++; + } + else { + row++; + column++; + } + if(isPiece(row, column)) { + if(getPiece(row, column)->getType() != piece->getType()) { + isTaken(row, column); + piece->moveRight(); + } + } + else { + //cout << piece->getX() << " " << piece->getY() << "\n\n"; + piece->moveRight(); + //cout << piece->getX() << " " << piece->getY() << "\n\n"; + } + } + setValidTrue(); + } + else + { + cout << "Invalid move.\n\n"; + setValidFalse(); + } + } + + return *this; +} + +bool Board::isThisMovePossible(int r, int c, string moveType){ + Piece* piece; + Piece* temp; + if (isPiece(r, c)) + piece = getPiece(r, c); + else + return false; + + if (piece->getType() != turn) { + cout << "Error in Board::isThisMovePossible: trying to move a piece outside your turn.\n"; + return false; + } + + else{ + int reflector = 1; + + if (piece->getType() == 'O') + reflector = -1; + + if (moveType == "FWD"){ + if (!isPiece(r + reflector, c)) + return true; + else + return false; + } + + else if (moveType == "RIGHT"){ + temp = getPiece(r + reflector, c+1); + if(c < 7) { + if (!isPiece(r+reflector, c+1) && (r+reflector >= 0) && (r+reflector <= 7) && (c+1 <= 7)) { + //cout << "What.\n\n"; + return true; + } + else if(temp->getType() != piece->getType()) { + char a = temp->getType(); + char b = piece->getType(); + //cout << a << " " << b << "\n\n"; + return true; + } + else { + return false; + } + } + else { + return false; + } + } + + else if (moveType == "LEFT"){ + temp = getPiece(r + reflector, c-1); + if(c > 0) { + if (!isPiece(r+reflector, c-1) && (r+reflector >= 0) && (r+reflector <= 7)) { + //cout << "What.\n\n"; + return true; + } + else if(temp->getType() != piece->getType()) { + char a = temp->getType(); + char b = piece->getType(); + //cout << a << " " << b << "\n\n"; + return true; + } + else { + return false; + } + } + else { + return false; + } + } + + else return false; + } +} + +vector Board::viewPossibleMoves(){ + int r, c = -1; + vector output; + + if (turn == 'X'){ + for (int i = 0; i < xpieces.size(); ++i){ + r = xpieces[i]->getX(); + c = xpieces[i]->getY(); + if (isThisMovePossible(r, c, "FWD")) + { + moves temp(8-r,c, "FWD"); + output.push_back(temp); + } + + if (isThisMovePossible(r,c,"LEFT")) + { + moves temp(8-r,c, "LEFT"); + output.push_back(temp); + } + + if (isThisMovePossible(r,c,"RIGHT")) + { + moves temp(8-r,c, "RIGHT"); + output.push_back(temp); + } + } + } + + else if (turn == 'O') { + for (int i = 0; i < opieces.size(); ++i){ + r = opieces[i]->getX(); + c = opieces[i]->getY(); + if (isThisMovePossible(r, c, "FWD")) + { + moves temp(8-r,c, "FWD"); + output.push_back(temp); + } + + if (isThisMovePossible(r,c,"LEFT")) + { + moves temp(8-r,c, "LEFT"); + output.push_back(temp); + } + + if (isThisMovePossible(r,c,"RIGHT")) + { + moves temp(8-r,c, "RIGHT"); + output.push_back(temp); + } + } + } + + return output; +} + +string Board::myToUpper(string input){ + string output; + + for (int i = 0 ; i < input.size(); ++i) + { + int numeric; + + if ((input[i] - 0 >= 97) && (input[i] - 0 <= 122)) + { + numeric = input[i] - 32; + output.push_back((char)numeric); + } + else output.push_back(input[i]); + } + + return output; + +} + +void Board::undo(Board& tablero){ + vector record; + + if (record.size() < 2){ + cout<<"nothing to undo"< record; + input = myToUpper(input); + + if (input == "UNDO"){ + undo(tablero); + } + + else if (input == "DISPLAYRECORD"){ + cout<<"record: "<& inputVec, Board inputBoard){ + if (inputVec.size() == 10){ + inputVec.erase(inputVec.begin()); + } + + else if (inputVec.size() > 10){ + cout<<"QUEUE OVERFLOW!"< +#include +#include "Piece.h" + +using namespace std; + +struct moves { + int row; + int column; + string moveType; + + moves() { + row = -1; + column = -1; + moveType = ""; + } + + moves(int linea, int columna, string m) { + row = linea; + column = columna; + moveType = m; + } +}; + +class Board { + vector xpieces; + vector opieces; + vector pieces; + char turn = 'O'; + bool valid = false; + +public: + Board(); + Board(const Board& b); + void setValidFalse(){ valid = false; } + void setValidTrue(){ valid = true; } + bool isValid(){ return valid; } + bool isPiece(int r, int c); + Piece* getPiece(int r, int c); + void isTaken(int r, int c); + vector getXPieces() const { return xpieces; } + vector getOPieces() const { return opieces; } + char getTurnPls() const { return turn; } + moves parse(string input); + char getTurn() { return turn; } + bool isGameOver(); + string whoWon(); + void changeTurns(); + void displayBoard(); + string boardToString(); + int charToIntColumn(char input); + char intToCharColumn(int input); + void move(string inputMove); + Board move(moves m); + bool isThisMovePossible(int r, int c, string moveType); + vector viewPossibleMoves(); + string myToUpper(string input); + void undo(Board& tablero); + void interpret(string input, Board& tablero); + void snapshot(vector& inputVec, Board inputBoard); + int evaluate(char max, char min); +}; diff --git a/Client.java b/Client.java new file mode 100755 index 0000000..8f3d5f7 --- /dev/null +++ b/Client.java @@ -0,0 +1,271 @@ +// Alex Huddleston +// 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 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 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. + boardPanel.add(new JLabel("")); + // 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(url1); + 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(url2); + 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(board.charAt(i) == 'X') { + output += board.charAt(i); + } + + else if(board.charAt(i) == '_') { + output += board.charAt(i); + } + + else if(board.charAt(i) == 'O') { + output += board.charAt(i); + } + } + return output; + } + + public final void updateBoard(String board) { + board = TrimBoard(board); + int count = 0; + ImageIcon icon = new ImageIcon( new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB)); + 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++; + } + } + if(board.charAt(count) == 'X') { + boardSquares[7][7].setIcon(new ImageIcon(pieceImages[0])); + } + else if(board.charAt(count) == 'O') { + boardSquares[7][7].setIcon(new ImageIcon(pieceImages[1])); + } + else { + boardSquares[7][7].setIcon(icon); + } + } + + public void sendLocation(int r, int c) { + //debugging. + System.out.println("row: " + r + " col: " + c); + boardoutput += "" + r + "" + c; + } + + 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(); + System.out.print(temp); + //setBoard(temp); + //window.drawBoard(temp); + + 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(); + output.println(userInput); + + 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)) { + end = true; + } + } + System.out.println(String.valueOf(buffer).trim()); + window.updateBoard(String.valueOf(buffer).trim()); + while(!end && boardoutput.length() < 4) { + Thread.sleep(100); + } + System.out.println(boardoutput); + output.println(boardoutput); + output.flush(); + boardoutput = ""; + } + output.close(); + in.close(); + stdIn.close(); + echoSocket.close(); + } + catch (IOException e){ + System.err.println("IOException: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/Engine.cpp b/Engine.cpp new file mode 100644 index 0000000..185cb90 --- /dev/null +++ b/Engine.cpp @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include "Engine.h" + +Engine::Engine(){ + Board* brd = new Board(); + b = brd; +} + +void Engine::startGame(){ + cout<<"WELCOME\n"; + + cout<<"1. Play against AI?\n"; + cout<<"2. Play against a human?\n"; + cout<<"Enter choice: \n"; + + int choice = -1; + cin >> choice; + cout << "OK" << endl; + + string move; + + bool gameOver = false; + vector record; + b->snapshot(record, *b); + + while (gameOver != true){ + gameOver = b->isGameOver(); + + while(b->getTurn() == 'O' && !b->isValid()){ + b->displayBoard(); + cout<<"\nEnter command: "; + cin>>move; + cout << "\n"; + b->interpret(move, *b); + + if(b->isValid()){ + b->changeTurns(); + b->setValidFalse(); + } + } + + while(b->getTurn() == 'X' ){ + easyAI(); + //AI(3); + } + + gameOver = b->isGameOver(); + b->setValidFalse(); + + b->snapshot(record, *b); + } + b->displayBoard(); + string s = ""; + s += b->getTurn(); + cout << "Game over. " + s + " wins!\n\n"; +} + +void Engine::easyAI(){ + vector listOfMoves = b->viewPossibleMoves(); + + srand(time(NULL)); + int randomChoice = rand() % (listOfMoves.size()-1) - 0; + + b->move(listOfMoves[randomChoice]); + b->changeTurns(); +} + +void Engine::AI(int depth){ + Board* temp = new Board(*b); + moves empty; + MNode* root = new MNode(*temp, empty, 0); + + //only doing 1 branch right now because testing + /*for (int i = 0; i < listOfMoves.size(); ++i){ + minMax(b, listOfMoves[i]); + }*/ + + //remove this soon + //b->move(minMax(temp, listOfMoves[0], 0, 0)); + + b->changeTurns(); + b->displayBoard(); +} + +moves Engine::minMax(MNode* node, int depth){ + Board current = node->getState(); + vector listOfMoves = current.viewPossibleMoves(); + /* + if (current.isGameOver() == true){ + cout << "END OF PATH REACHED\n\n"; + return m; + } + + else { + if(current.getPiece(8 - m.row, m.column)->getType() == current.getTurn() && current.isThisMovePossible(8 - m.row, m.column, m.moveType)){ + temp->move(m); + temp->evaluate('X', 'O'); + temp->changeTurns(); + } + else { + m = minMax(temp, listOfMoves[++r], c, r); + } + + vector listOfMoves = temp->viewPossibleMoves(); + minMax(temp, listOfMoves[0], 0, 0); + return m; + } + */ +} diff --git a/Engine.h b/Engine.h new file mode 100644 index 0000000..89f3327 --- /dev/null +++ b/Engine.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Board.h" +#include "MNode.h" + +using namespace std; + +class Engine { + Board* b; + +public: + Engine(); + Board* getBoard() { return b; } + void startGame(); + void easyAI(); + void AI(int depth); + moves minMax(MNode* node, int depth); +}; diff --git a/MNode.cpp b/MNode.cpp new file mode 100755 index 0000000..8f4c410 --- /dev/null +++ b/MNode.cpp @@ -0,0 +1,43 @@ +#include +#include +#include "MNode.h" + +using namespace std; + +MNode::MNode(){ + children.clear(); + minimax_val = -1; +} + +MNode::MNode(Board s, moves m, int mmval){ + state = s; + mvs = m; + minimax_val = mmval; +} + +MNode::MNode(const MNode& n){ + children = n.getChildren(); + minimax_val = n.getMMVal(); +} + +void MNode::setMMVal(int mmval) { + minimax_val = mmval; +} + +bool MNode::hasChildren(){ + if (children.size() != 0) + return true; + else + return false; +} + +void printTree(int depth, const MNode& n){ + vector children; + cout << "depth " << depth << " :" << n.getMMVal() << " "; + children = n.getChildren(); + + //print out root + for (int i = 0; i < children.size(); ++i){ + printTree(++depth, *children[i]); + } +} \ No newline at end of file diff --git a/MNode.h b/MNode.h new file mode 100755 index 0000000..1afe963 --- /dev/null +++ b/MNode.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include "Board.h" + +using namespace std; + +class MNode { + vector children; + Board state; + moves mvs; + int minimax_val; + +public: + MNode(); + MNode(Board s, moves m, int mmval); + MNode(const MNode& n); + vector getChildren() const { return children; } + void addChild(MNode* n) { children.push_back(n); } + int getMMVal() const { return minimax_val; } + void setMMVal(int mmval); + Board getState() { return state; } + void setState(Board s) { state = s; } + moves getMove() { return mvs; } + void setMove(moves m) { mvs = m; } + bool hasChildren(); +}; + +void printTree(int depth, const MNode& n); \ No newline at end of file diff --git a/Piece.cpp b/Piece.cpp new file mode 100644 index 0000000..a438327 --- /dev/null +++ b/Piece.cpp @@ -0,0 +1,69 @@ +#include +#include "Piece.h" + +using namespace std; + +Piece::Piece(){ + x = -1; + y = -1; + type = '?'; +} + +Piece::Piece(int r, int c){ + x = r; + y = c; + type = '_'; +} + +Piece::Piece(int r, int c, char t){ + x = r; + y = c; + type = t; +} + +void Piece::moveFwd(){ + if (type == 'X'){ + x++; + } + + else if (type == 'O'){ + x--; + } + + else + cout << "Error: trying to move an empty piece forward."; +} + +void Piece::moveLeft(){ + if (type == 'X'){ + x++; + y--; + } + + else if (type == 'O'){ + x--; + y--; + } + + else + cout << "Error: trying to move an empty piece left."; +} + +void Piece::moveRight(){ + if (type == 'X'){ + x++; + y++; + } + + else if (type == 'O'){ + x--; + y++; + } + + else + cout << "Error: trying to move an empty piece left."; +} + +void Piece::isTaken(){ + cout << getX() << " " << getY() << "\n\n"; +} diff --git a/Piece.h b/Piece.h new file mode 100644 index 0000000..82f6bed --- /dev/null +++ b/Piece.h @@ -0,0 +1,24 @@ +#pragma once + +using namespace std; + +class Piece { + int x; + int y; + char type; + +public: + Piece(); + Piece(int r, int c); + Piece(int r, int c, char t); + void moveFwd(); + void moveLeft(); + void moveRight(); + int getX(){ return x; } + void setX(int r){ x = r; } + int getY(){ return y; } + void setY(int c){ y = c; } + char getType(){ return type; } + void makeEmpty(){ type = '_'; } + void isTaken(); +}; diff --git a/README.md b/README.md index e5895c3..4eb839f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ # Breakthrough Reposity for the second CSCE 315 project + +# To compile everything: + make + or make all + + ***NOTE*** + To remove all .class and .o files, just use: make clean. + +# To run test: + ./test + +# To launch the server: + ./server [port #] + +Java Client is now functional with GUI. + +# To launch the client: + java Client [server address] [port #] + Where [server address] is linux.cs.tamu.edu (or whatever server you're on) and [port #] is the same as server's [port #]. + +# Troubleshooting: +- Make sure you enable X11 forwarding in your PuTTY settings before you start your connection to the linux server. +- Make sure you also open XLaunch and just click next until finish so that PuTTY doesn't whine about not having a server to start up the client with. +- You will need to manually enter "1" when you start the client. Haven't gotten around to doing that frame just yet, but mostly because the AI stuff isn't finished yet. +- The GUI takes two moves at a time, to play click the square with the piece you want to move, then the square you want to move it to. Remember there is very minimal error checking on the GUI side, so if you make an incorrect move, the server will just yell at you and the client will continue like nothing happened. I left in some Debugging output on both the Client and Server side so you guys can tell where you messed up. Let me know if you experience any bugs. +- The game will not automatically close on Game Over, you will have to close the window yourself, but that's not exactly a bug, so I'm just going to leave it in. +- Be patient. Swing is very slow and it'll take a second or two for it to initialize the window and a couple seconds to render the icons each time you make a move (depending on if you're using a VPN or not, runs smoothly on campus). diff --git a/makefile b/makefile new file mode 100755 index 0000000..7adedd8 --- /dev/null +++ b/makefile @@ -0,0 +1,21 @@ +# makefile + +all: test server Client.class + +server: Server.o + g++ -std=c++11 -o server Server.o Engine.o Piece.o Board.o MNode.o + +Server.o: Server.cpp Engine.cpp Board.cpp Piece.cpp MNode.cpp + g++ -std=c++11 -c -g Server.cpp Engine.cpp Board.cpp Piece.cpp MNode.cpp + +test: test.o + g++ -std=c++11 -o test test.o Engine.o Piece.o Board.o MNode.o + +test.o: test.cpp Engine.cpp Board.cpp Piece.cpp MNode.cpp + g++ -std=c++11 -c -g test.cpp Engine.cpp Board.cpp Piece.cpp MNode.cpp + +Client.class: Client.java + javac -g Client.java + +clean: + $(RM) *.class *.o \ No newline at end of file diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..c26c406 --- /dev/null +++ b/test.cpp @@ -0,0 +1,10 @@ +#include "Engine.h" + +using namespace std; + +int main() +{ + //Board b; + Engine e; + e.startGame(); +}