Merge
This commit is contained in:
47
src/Main.java
Normal file
47
src/Main.java
Normal file
@@ -0,0 +1,47 @@
|
||||
import board.Board;
|
||||
import events.FourInARow;
|
||||
import events.IWinCondition;
|
||||
import interfaces.FourInARowGUI;
|
||||
import interfaces.NInARowGUI;
|
||||
import interfaces.TicTacToeGUI;
|
||||
import objects.Empty;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
class Main {
|
||||
private static final int BOARD_WIDTH = 7;
|
||||
private static final int BOARD_HEIGHT = 6;
|
||||
private enum Gamemode {TICTACTOE, FOURINAROWCLASSIC, FOURINAROW}
|
||||
|
||||
public static void main(String[] args) {
|
||||
HashMap<String, Gamemode> modeList = new HashMap<>();
|
||||
modeList.put("Tic-Tac-Toe", Gamemode.TICTACTOE);
|
||||
modeList.put("Four in a row classic", Gamemode.FOURINAROWCLASSIC);
|
||||
modeList.put("Four in a row", Gamemode.FOURINAROW);
|
||||
Object[] keys = modeList.keySet().toArray();
|
||||
|
||||
String selectedValue = (String)JOptionPane.showInputDialog(null, "Select a game from the list below:", "Car model...", JOptionPane.QUESTION_MESSAGE,null, keys, keys[0]);
|
||||
if (selectedValue == null) {
|
||||
System.exit(0);
|
||||
}
|
||||
List<IWinCondition> con = new ArrayList<>();
|
||||
con.add(new FourInARow());
|
||||
switch (modeList.get(selectedValue)) {
|
||||
case TICTACTOE:
|
||||
new TicTacToeGUI();
|
||||
break;
|
||||
case FOURINAROWCLASSIC:
|
||||
new FourInARowGUI(BOARD_WIDTH, BOARD_HEIGHT, new Board(BOARD_WIDTH, BOARD_HEIGHT, new Empty(), con));
|
||||
break;
|
||||
case FOURINAROW:
|
||||
new NInARowGUI(BOARD_WIDTH, BOARD_HEIGHT, new Board(BOARD_WIDTH, BOARD_HEIGHT, new Empty(), con));
|
||||
break;
|
||||
default:
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
70
src/Plan.txt
Normal file
70
src/Plan.txt
Normal file
@@ -0,0 +1,70 @@
|
||||
Two dimensional array.
|
||||
Render each subarray from bottom to top.
|
||||
Place each piece in the start of the array.
|
||||
|
||||
Let user choose from a button above each row where to place a chip.
|
||||
|
||||
Keep count of player names and colors, maybe with some text input.
|
||||
objects.Player has name and color.
|
||||
|
||||
Turn + Events
|
||||
|
||||
Width = 7, Height = 6
|
||||
|
||||
Check from each block of a color (maybe keep track of blocked pieces for effectiveness).
|
||||
Maybe allow for custom combinations required to win.
|
||||
|
||||
Game
|
||||
- Winning Conditions
|
||||
- board.Board
|
||||
- GameObjects
|
||||
- Random events
|
||||
- Input/Output
|
||||
- Players
|
||||
|
||||
Players
|
||||
Class with info about player <- passive
|
||||
- name
|
||||
- color (of token)
|
||||
|
||||
Interface for a player's actions <- active
|
||||
- Methods for throwing token into column.
|
||||
- +Info
|
||||
|
||||
Input/Output
|
||||
- Input interface
|
||||
* int getNextColumn(objects.Player p); //Retrieve user input
|
||||
- Output interface
|
||||
* void displayBoard(board.IBoard b);
|
||||
* void displayMessage(String s);
|
||||
|
||||
Random Events
|
||||
- Interface events.IRandomEvent
|
||||
* void act(board.IBoard b);
|
||||
* String announcement();
|
||||
|
||||
events.IRandomEvent
|
||||
Abstract events.RandomEvent implements events.IRandomEvent (void flipCoin // Does something if heads)
|
||||
Shuffle extends events.RandomEvent
|
||||
|
||||
objects.GameObject
|
||||
objects.Token
|
||||
Owner instanceof objects.Player
|
||||
|
||||
GameObjects(objects.Token, empty)
|
||||
* One class
|
||||
* getColor();
|
||||
|
||||
Winning Conditions
|
||||
- Interface events.IWinCondition
|
||||
* boolean hasWon(objects.Player p, board.IBoard board);
|
||||
|
||||
|
||||
"Main" method (Game)
|
||||
- Outer loop: "While the game has not been finished"
|
||||
1) Determine who's turn
|
||||
2) Get next input: int j = input.getNextColumn(p);
|
||||
3) Execute move: p throws in column j.
|
||||
4) Check if p has won.
|
||||
5) Update view (output.displayBoard())
|
||||
6) events.RandomEvent.act();
|
149
src/board/Board.java
Normal file
149
src/board/Board.java
Normal file
@@ -0,0 +1,149 @@
|
||||
package board;
|
||||
|
||||
import events.IWinCondition;
|
||||
import objects.GameObject;
|
||||
import objects.Player;
|
||||
import objects.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Board implements IBoard{
|
||||
private final Grid<GameObject> grid;
|
||||
private final List<Player> players;
|
||||
private int playersTurn = 0;
|
||||
private final List<IWinCondition> conditionList;
|
||||
private boolean won = false;
|
||||
|
||||
public Board(int width, int height, GameObject obj, List<IWinCondition> conditions) {
|
||||
grid = new Grid<>(width, height, obj);
|
||||
players = new ArrayList<>();
|
||||
conditionList = conditions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPlayer(Player p) {
|
||||
if (!playerExists(p)) {
|
||||
players.add(p);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<Player> getPlayers() {
|
||||
return new ArrayList<>(players);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next player.
|
||||
*
|
||||
* @return A Player
|
||||
*/
|
||||
public Player nextPlayer() {
|
||||
Player p = players.get(playersTurn);
|
||||
this.playersTurn = this.playersTurn + 2 > this.players.size() ? 0 : this.playersTurn + 1;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure we don't have two equal players.
|
||||
*
|
||||
* @param player The new player to test
|
||||
* @return True if the player is non-unique
|
||||
*/
|
||||
private boolean playerExists(Player player) {
|
||||
for (Player p : players) {
|
||||
if (player.equals(p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return grid.isFull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if anyone has won.
|
||||
*
|
||||
* @param i The column of the last dropped object
|
||||
*/
|
||||
private void checkWin(int i) {
|
||||
for (IWinCondition con : conditionList) {
|
||||
if (con.hasWon(i, getTopObject(i), this)) {
|
||||
won = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if anyone has won.
|
||||
*
|
||||
* @param x The x-coordinate of the last dropped object
|
||||
* @param y The y-coordinate of the last dropped object
|
||||
*/
|
||||
private void checkWin(int x, int y) {
|
||||
for (IWinCondition con : conditionList) {
|
||||
if (con.hasWon(x, y, this)) {
|
||||
won = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean won() {
|
||||
return won;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
grid.flush();
|
||||
playersTurn = 0;
|
||||
won = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTopObject(int column) {
|
||||
return grid.getTopObject(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return grid.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return grid.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int x, int y, GameObject element) {
|
||||
grid.set(x, y, element);
|
||||
if (element instanceof Token) {
|
||||
checkWin(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drop(int i, GameObject element) {
|
||||
boolean dropped = grid.drop(i, element);
|
||||
if (element instanceof Token) {
|
||||
checkWin(i);
|
||||
}
|
||||
return dropped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameObject get(int x, int y) { return grid.get(x, y); }
|
||||
|
||||
@Override
|
||||
public IGrid<GameObject> copy() {
|
||||
return grid.copy();
|
||||
}
|
||||
}
|
100
src/board/Grid.java
Normal file
100
src/board/Grid.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package board;
|
||||
|
||||
import objects.Token;
|
||||
|
||||
public class Grid<T> implements IGrid<T> {
|
||||
private final T[][] grid;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final T empty;
|
||||
|
||||
public Grid(int width, int height, T object) {
|
||||
T[][] list = (T[][])new Object[width][height];
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
list[i][j] = object;
|
||||
}
|
||||
}
|
||||
grid = list;
|
||||
this.empty = object;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
grid[i][j] = empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
int empty = 0;
|
||||
for (T[] list : grid) {
|
||||
for (T item : list) {
|
||||
if (this.empty.getClass().isInstance(item)) {
|
||||
empty++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return empty < 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTopObject(int column) {
|
||||
for (int j = this.height - 1; j > -1; j--) {
|
||||
if (grid[column][j] instanceof Token) {
|
||||
return j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drop(int i, T element) {
|
||||
if (i > width || i < 0) {
|
||||
throw new IllegalArgumentException("Index out of bounds.");
|
||||
}
|
||||
for (int j = 0; j < this.height; j++) {
|
||||
if (this.empty.getClass().isInstance(grid[i][j])) {
|
||||
grid[i][j] = element;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int x, int y, T element) {
|
||||
if (x > width || y > height || x < 0 || y < 0) {
|
||||
throw new IllegalArgumentException("Index out of bounds.");
|
||||
}
|
||||
grid[x][y] = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int x, int y) {
|
||||
if (y >= height || x >= width || x < 0 || y < 0) {
|
||||
throw new IllegalArgumentException("Index out of bound.");
|
||||
}
|
||||
return grid[x][y];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGrid<T> copy() {
|
||||
Grid<T> newGrid = new Grid<>(width, height, empty);
|
||||
System.arraycopy(grid, 0, newGrid.grid, 0, width);
|
||||
return newGrid;
|
||||
}
|
||||
}
|
50
src/board/IBoard.java
Normal file
50
src/board/IBoard.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package board;
|
||||
|
||||
import objects.GameObject;
|
||||
import objects.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IBoard extends IGrid<GameObject> {
|
||||
/**
|
||||
* Adds a new player to the board.
|
||||
*
|
||||
* @param p The player to add
|
||||
* @return True if the player is valid
|
||||
*/
|
||||
boolean addPlayer(Player p);
|
||||
|
||||
/**
|
||||
* Gets the next player from the board.
|
||||
*
|
||||
* @return A player
|
||||
*/
|
||||
Player nextPlayer();
|
||||
|
||||
/**
|
||||
* Find out if someone has won.
|
||||
*
|
||||
* @return True if someone won
|
||||
*/
|
||||
boolean won();
|
||||
|
||||
/**
|
||||
* Flushes all values in the board.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Gets the position of the topmost object in the board's grid.
|
||||
*
|
||||
* @param column The target column
|
||||
* @return A position or -1 if all rows are empty
|
||||
*/
|
||||
int getTopObject(int column);
|
||||
|
||||
/**
|
||||
* Gets a copy of the players list.
|
||||
*
|
||||
* @return A list of players
|
||||
*/
|
||||
List<Player> getPlayers();
|
||||
}
|
70
src/board/IGrid.java
Normal file
70
src/board/IGrid.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package board;
|
||||
|
||||
public interface IGrid<T> {
|
||||
|
||||
/**
|
||||
* @return The height of the grid.
|
||||
*/
|
||||
int getHeight();
|
||||
|
||||
/**
|
||||
* @return The width of the grid.
|
||||
*/
|
||||
int getWidth();
|
||||
|
||||
/**
|
||||
*
|
||||
* Set the contents of the cell in the given x,y location.
|
||||
*
|
||||
* y must be greater than or equal to 0 and less than getHeight().
|
||||
* x must be greater than or equal to 0 and less than getWidth().
|
||||
*
|
||||
* @param x The column of the cell to change the contents of.
|
||||
* @param y The row of the cell to change the contents of.
|
||||
* @param element The contents the cell is to have.
|
||||
*/
|
||||
void set(int x, int y, T element);
|
||||
|
||||
/**
|
||||
* Drops an element into column i.
|
||||
*
|
||||
* @param i The target column
|
||||
* @param element The element to be dropped
|
||||
* @return True if the column had space for the element
|
||||
*/
|
||||
boolean drop(int i, T element);
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the contents of the cell in the given x,y location.
|
||||
*
|
||||
* y must be greater than or equal to 0 and less than getHeight().
|
||||
* x must be greater than or equal to 0 and less than getWidth().
|
||||
*
|
||||
* @param x The column of the cell to get the contents of.
|
||||
* @param y The row of the cell to get contents of.
|
||||
*/
|
||||
T get(int x, int y);
|
||||
|
||||
/**
|
||||
* Make a copy
|
||||
*
|
||||
* @return A fresh copy of the grid, with the same elements
|
||||
*/
|
||||
IGrid<T> copy();
|
||||
|
||||
/**
|
||||
* Checks if the grid is absolutely full.
|
||||
*
|
||||
* @return True if it is full
|
||||
*/
|
||||
boolean isFull();
|
||||
|
||||
/**
|
||||
* Retrieves the position of the topmost element from a column.
|
||||
*
|
||||
* @param column The target column
|
||||
* @return The y-position of the top element
|
||||
*/
|
||||
int getTopObject(int column);
|
||||
}
|
17
src/events/Block.java
Normal file
17
src/events/Block.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
import objects.Immovable;
|
||||
|
||||
public class Block extends RandomEvent {
|
||||
@Override
|
||||
public void act(IBoard b) {
|
||||
int x = random.nextInt(b.getWidth());
|
||||
b.drop(x, new Immovable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String announcement() {
|
||||
return "An immovable object was placed.";
|
||||
}
|
||||
}
|
47
src/events/Bomb.java
Normal file
47
src/events/Bomb.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
import objects.Empty;
|
||||
import objects.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Bomb extends RandomEvent {
|
||||
@Override
|
||||
public void act(IBoard b) {
|
||||
int x = random.nextInt(b.getWidth());
|
||||
int y = b.getTopObject(x);
|
||||
for (ArrayList<Integer> list : generateSquare(b, x, y, random.nextInt(2) + 1)) {
|
||||
b.set(list.get(0), list.get(1), new Empty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all locations in a square a range from a point.
|
||||
*
|
||||
* @param b A board
|
||||
* @param x The x index of the starting point
|
||||
* @param y The y index of the starting point
|
||||
* @param range The range of the square
|
||||
* @return A list of lists of integers
|
||||
*/
|
||||
private ArrayList<ArrayList<Integer>> generateSquare(IBoard b, int x, int y, int range) {
|
||||
ArrayList<ArrayList<Integer>> locations = new ArrayList<>();
|
||||
for (int i = x - range; i <= x + range; i++) {
|
||||
for (int j = y - range; j <= y + range; j++) {
|
||||
if (i >= 0 && i < b.getWidth() && j >= 0 && j < b.getHeight() && b.get(i, j) instanceof Token) {
|
||||
ArrayList<Integer> coords = new ArrayList<>();
|
||||
coords.add(i);
|
||||
coords.add(j);
|
||||
locations.add(coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String announcement() {
|
||||
return "A bomb just exploded!";
|
||||
}
|
||||
}
|
10
src/events/FourInARow.java
Normal file
10
src/events/FourInARow.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
|
||||
public class FourInARow extends InARow {
|
||||
@Override
|
||||
public boolean hasWon(int x, int y, IBoard board) {
|
||||
return hasWon(x, y, board, 3);
|
||||
}
|
||||
}
|
8
src/events/IRandomEvent.java
Normal file
8
src/events/IRandomEvent.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
|
||||
public interface IRandomEvent {
|
||||
void act(IBoard b);
|
||||
String announcement();
|
||||
}
|
18
src/events/IWinCondition.java
Normal file
18
src/events/IWinCondition.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
|
||||
/**
|
||||
* A condition for winning the game.
|
||||
*/
|
||||
public interface IWinCondition {
|
||||
/**
|
||||
* Checks if someone has won according to the custom conditions.
|
||||
*
|
||||
* @param x The x-coordinate of the last placed element
|
||||
* @param y The y-coordinate of the last placed element
|
||||
* @param board The board to check
|
||||
* @return True if someone has won
|
||||
*/
|
||||
boolean hasWon(int x, int y, IBoard board);
|
||||
}
|
47
src/events/InARow.java
Normal file
47
src/events/InARow.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Contains methods for implementing any n in a row rules.
|
||||
*/
|
||||
abstract class InARow implements IWinCondition {
|
||||
/**
|
||||
* Checks if the supplied position has enough neighbours in a straight line of the same type
|
||||
*
|
||||
* @param x The x-coordinate of the start position
|
||||
* @param y The y-coordinate of the start position
|
||||
* @param board The board on which to perform the task
|
||||
* @param t The number of elements in a row, which constitutes a win (excluding start position)
|
||||
* @return True if x, y was a winning move
|
||||
*/
|
||||
static boolean hasWon(int x, int y, IBoard board, int t) {
|
||||
return count(x, y, 1, 0, board) + count(x, y, -1, 0, board) >= t ||
|
||||
count(x, y, 0, -1, board) + count(x, y, 0, 1, board) >= t ||
|
||||
count(x, y, 1, 1, board) + count(x, y, -1, -1, board) >= t ||
|
||||
count(x, y, 1, -1, board) + count(x, y, -1, 1, board) >= t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts all elements from a start position in a set direction with a matching color.
|
||||
*
|
||||
* @param x The x-coordinate of the start position
|
||||
* @param y The y-coordinate of the start position
|
||||
* @param iX Step amount in x-direction
|
||||
* @param iY Step amount in y-direction
|
||||
* @param b The board on which to perform the task
|
||||
* @return The number of elements found
|
||||
*/
|
||||
private static int count(int x, int y, int iX, int iY, IBoard b) {
|
||||
int count = 0;
|
||||
Color target = b.get(x, y).getColor();
|
||||
while ((y + iY >= 0 && y + iY < b.getHeight()) && (x + iX >= 0 && x + iX < b.getWidth()) && b.get(x + iX, y + iY).getColor() == target) {
|
||||
x += iX;
|
||||
y += iY;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
43
src/events/RandomEvent.java
Normal file
43
src/events/RandomEvent.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Contains basic probability methods usable by all random events.
|
||||
*/
|
||||
public abstract class RandomEvent implements IRandomEvent {
|
||||
final Random random = new Random();
|
||||
|
||||
/**
|
||||
* Flips a coin, and acts if it comes out as head.
|
||||
*
|
||||
* @param b The board to act on
|
||||
* @return True if somehting happened. False otherwise
|
||||
*/
|
||||
public boolean flipCoin(IBoard b) {
|
||||
if (random.nextInt(2) > 0) {
|
||||
act(b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolls n die, and acts if all die got a "6".
|
||||
*
|
||||
* @param b The board to act on
|
||||
* @param n The number of die
|
||||
* @return True if something happened. False otherwise
|
||||
*/
|
||||
public boolean rollDie(IBoard b, int n) {
|
||||
if (random.nextInt((int)Math.pow(6, n)) < 1) {
|
||||
act(b);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract void act(IBoard b);
|
||||
}
|
10
src/events/ThreeInARow.java
Normal file
10
src/events/ThreeInARow.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package events;
|
||||
|
||||
import board.IBoard;
|
||||
|
||||
public class ThreeInARow extends InARow {
|
||||
@Override
|
||||
public boolean hasWon(int x, int y, IBoard board) {
|
||||
return hasWon(x, y, board, 2);
|
||||
}
|
||||
}
|
136
src/interfaces/FourInARowGUI.java
Normal file
136
src/interfaces/FourInARowGUI.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package interfaces;
|
||||
|
||||
import board.IBoard;
|
||||
import objects.GameObject;
|
||||
import objects.Player;
|
||||
import objects.Token;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
public class FourInARowGUI extends GUI {
|
||||
|
||||
public FourInARowGUI(int width, int height, IBoard board) {
|
||||
if (width < 3 || height < 3 || height > 50 || width > 50) {
|
||||
throw new IllegalArgumentException("Invalid game size.");
|
||||
}
|
||||
if (width != board.getWidth() || height != board.getHeight()) {
|
||||
throw new IllegalArgumentException("The board does not match the gui.");
|
||||
}
|
||||
this.board = board;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
String playerName = "";
|
||||
while (playerName.equals("")) {
|
||||
playerName = JOptionPane.showInputDialog(String.format("Name of player %d: ", i+1));
|
||||
if (playerName == null) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
Color color;
|
||||
if (i == 0) {
|
||||
color = Color.green;
|
||||
} else {
|
||||
color = Color.red;
|
||||
}
|
||||
Player player = new Player(playerName, color);
|
||||
if (!this.board.addPlayer(player)) {
|
||||
JOptionPane.showMessageDialog(null, "Player is not unique. Please try again.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
initialize(width, height);
|
||||
}
|
||||
|
||||
private void initialize(int width, int height) {
|
||||
JFrame frame = new JFrame("Four in a row");
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
int fullWidth = BUTTON_WIDTH * width + (WIDTH_GAP + 1) * width;
|
||||
int fullHeight = BUTTON_HEIGHT + (TILE_HEIGHT * height) + HEIGHT_GAP * (height) + TILE_HEIGHT;
|
||||
|
||||
this.frame = frame;
|
||||
JPanel container = new JPanel();
|
||||
container.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
container.setPreferredSize(new Dimension(fullWidth, fullHeight + TILE_HEIGHT + BUTTON_HEIGHT));
|
||||
frame.add(container);
|
||||
|
||||
JPanel panel3 = new JPanel();
|
||||
this.resetButton = new JButton("Reset");
|
||||
this.resetButton.addActionListener(this);
|
||||
panel3.add(this.resetButton);
|
||||
for (Player player : board.getPlayers()) {
|
||||
JLabel playerLabel = new JLabel(player.toString());
|
||||
playerLabel.setForeground(player.getColor());
|
||||
panel3.add(playerLabel);
|
||||
}
|
||||
container.add(panel3);
|
||||
|
||||
JPanel panel2 = new JPanel();
|
||||
this.mainPanel = panel2;
|
||||
panel2.setBackground(Color.BLUE);
|
||||
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, HEIGHT_GAP, WIDTH_GAP));
|
||||
panel2.setPreferredSize(new Dimension(fullWidth, fullHeight));
|
||||
dropButtons = new JButton[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
JButton button = new JButton();
|
||||
button.addActionListener(this);
|
||||
button.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
|
||||
dropButtons[i] = button;
|
||||
panel2.add(button, BorderLayout.PAGE_START);
|
||||
}
|
||||
tiles = new JTextPane[width * height];
|
||||
readTiles();
|
||||
container.add(panel2);
|
||||
|
||||
infoLabel = new JLabel();
|
||||
infoLabel.setPreferredSize(new Dimension(fullWidth, BUTTON_HEIGHT));
|
||||
infoLabel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
container.add(infoLabel);
|
||||
|
||||
frame.validate();
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
this.currentPlayer = board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() == this.resetButton) {
|
||||
this.board.flush();
|
||||
displayBoard();
|
||||
this.currentPlayer = this.board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
if (!(this.board.won() || this.board.isFull())) {
|
||||
for (int i = 0; i < this.dropButtons.length; i++) {
|
||||
if (e.getSource() == this.dropButtons[i]) {
|
||||
if (dropObject(i)) {
|
||||
displayBoard();
|
||||
if (!this.board.won()) {
|
||||
if (board.isFull()) {
|
||||
displayMessage("It's a draw");
|
||||
} else {
|
||||
this.currentPlayer = board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
} else {
|
||||
GameObject winnerObject = this.board.get(i, this.board.getTopObject(i));
|
||||
displayMessage(((Token)winnerObject).getOwner() + " won.");
|
||||
}
|
||||
} else {
|
||||
displayMessage("That column is full.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
src/interfaces/GUI.java
Normal file
61
src/interfaces/GUI.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package interfaces;
|
||||
|
||||
import board.IBoard;
|
||||
import objects.GameObject;
|
||||
import objects.Player;
|
||||
import objects.Token;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public abstract class GUI implements ActionListener, IGameInterface {
|
||||
final int BUTTON_HEIGHT = 25;
|
||||
final int BUTTON_WIDTH = 50;
|
||||
final int TILE_HEIGHT = 50;
|
||||
final int HEIGHT_GAP = 10;
|
||||
final int WIDTH_GAP = 10;
|
||||
|
||||
JButton[] dropButtons;
|
||||
JButton resetButton;
|
||||
JTextPane[] tiles;
|
||||
JLabel infoLabel;
|
||||
IBoard board;
|
||||
JPanel mainPanel;
|
||||
JFrame frame;
|
||||
|
||||
Player currentPlayer;
|
||||
|
||||
public void displayBoard() {
|
||||
for (JTextPane pane : this.tiles) {
|
||||
this.mainPanel.remove(pane);
|
||||
}
|
||||
this.tiles = new JTextPane[this.board.getWidth() * this.board.getHeight()];
|
||||
readTiles();
|
||||
this.frame.validate();
|
||||
}
|
||||
|
||||
void readTiles() {
|
||||
int k = 0;
|
||||
for (int i = board.getHeight() - 1; i > -1; i--) {
|
||||
for (int j = 0; j < board.getWidth(); j++) {
|
||||
JTextPane textPane = new JTextPane();
|
||||
this.tiles[k++] = textPane;
|
||||
textPane.setEditable(false);
|
||||
textPane.setBackground(Color.BLUE);
|
||||
GameObject obj = board.get(j,i);
|
||||
textPane.setBorder(BorderFactory.createLineBorder(obj.getColor(), 50, true));
|
||||
textPane.setPreferredSize(new Dimension(BUTTON_WIDTH, TILE_HEIGHT));
|
||||
mainPanel.add(textPane, BorderLayout.PAGE_START);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean dropObject(int i) {
|
||||
return this.board.drop(i, new Token(currentPlayer));
|
||||
}
|
||||
|
||||
public void displayMessage(String s) {
|
||||
infoLabel.setText(s);
|
||||
}
|
||||
}
|
6
src/interfaces/IGameInterface.java
Normal file
6
src/interfaces/IGameInterface.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package interfaces;
|
||||
|
||||
interface IGameInterface {
|
||||
void displayMessage(String s);
|
||||
void displayBoard();
|
||||
}
|
181
src/interfaces/NInARowGUI.java
Normal file
181
src/interfaces/NInARowGUI.java
Normal file
@@ -0,0 +1,181 @@
|
||||
package interfaces;
|
||||
|
||||
import board.IBoard;
|
||||
import events.Block;
|
||||
import events.Bomb;
|
||||
import objects.GameObject;
|
||||
import objects.Player;
|
||||
import objects.Token;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
public class NInARowGUI extends GUI {
|
||||
private Bomb bomb = new Bomb();
|
||||
private Block block = new Block();
|
||||
private JLabel eventLabel;
|
||||
|
||||
public NInARowGUI(int width, int height, IBoard board) {
|
||||
if (width < 3 || height < 3 || height > 50 || width > 50) {
|
||||
throw new IllegalArgumentException("Invalid game size.");
|
||||
}
|
||||
if (width != board.getWidth() || height != board.getHeight()) {
|
||||
throw new IllegalArgumentException("The board does not match the gui.");
|
||||
}
|
||||
this.board = board;
|
||||
int playerNum = 0;
|
||||
while (playerNum == 0) {
|
||||
try {
|
||||
String num = JOptionPane.showInputDialog("Number of players: ");
|
||||
if (num == null) {
|
||||
System.exit(0);
|
||||
}
|
||||
playerNum = Integer.parseInt(num);
|
||||
if (playerNum > width) {
|
||||
JOptionPane.showMessageDialog(null, "Number of players can't be higher than " + width, "Error", JOptionPane.ERROR_MESSAGE);
|
||||
playerNum = 0;
|
||||
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(null, "Invalid input.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < playerNum; i++) {
|
||||
String playerName = "";
|
||||
while (playerName.equals("")) {
|
||||
playerName = JOptionPane.showInputDialog(String.format("Name of player %d: ", i+1));
|
||||
if (playerName == null) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
Color color = null;
|
||||
while (color == null) {
|
||||
color = JColorChooser.showDialog(null, "Choose a color", Color.RED);
|
||||
if (color == null) {
|
||||
System.exit(0);
|
||||
}
|
||||
if (color == Color.lightGray || color == Color.blue || color == Color.black) {
|
||||
JOptionPane.showMessageDialog(null, "The chosen color is reserved. Please choose another color.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
color = null;
|
||||
}
|
||||
}
|
||||
Player player = new Player(playerName, color);
|
||||
if (!this.board.addPlayer(player)) {
|
||||
JOptionPane.showMessageDialog(null, "Player is not unique. Please try again.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
initialize(width, height);
|
||||
}
|
||||
|
||||
private void initialize(int width, int height) {
|
||||
JFrame frame = new JFrame("Four in a row");
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
int fullWidth = BUTTON_WIDTH * width + (WIDTH_GAP + 1) * width;
|
||||
int fullHeight = BUTTON_HEIGHT + (TILE_HEIGHT * height) + HEIGHT_GAP * (height) + TILE_HEIGHT;
|
||||
|
||||
this.frame = frame;
|
||||
JPanel container = new JPanel();
|
||||
container.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
container.setPreferredSize(new Dimension(fullWidth, fullHeight + TILE_HEIGHT + 2 * BUTTON_HEIGHT));
|
||||
frame.add(container);
|
||||
|
||||
JPanel panel3 = new JPanel();
|
||||
this.resetButton = new JButton("Reset");
|
||||
this.resetButton.addActionListener(this);
|
||||
panel3.add(this.resetButton);
|
||||
for (Player player : board.getPlayers()) {
|
||||
JLabel playerLabel = new JLabel(player.toString());
|
||||
playerLabel.setForeground(player.getColor());
|
||||
panel3.add(playerLabel);
|
||||
}
|
||||
container.add(panel3);
|
||||
|
||||
JPanel panel2 = new JPanel();
|
||||
this.mainPanel = panel2;
|
||||
panel2.setBackground(Color.BLUE);
|
||||
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, HEIGHT_GAP, WIDTH_GAP));
|
||||
panel2.setPreferredSize(new Dimension(fullWidth, fullHeight));
|
||||
dropButtons = new JButton[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
JButton button = new JButton();
|
||||
button.addActionListener(this);
|
||||
button.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
|
||||
dropButtons[i] = button;
|
||||
panel2.add(button, BorderLayout.PAGE_START);
|
||||
}
|
||||
tiles = new JTextPane[width * height];
|
||||
readTiles();
|
||||
container.add(panel2);
|
||||
|
||||
infoLabel = new JLabel();
|
||||
infoLabel.setPreferredSize(new Dimension(fullWidth, BUTTON_HEIGHT));
|
||||
infoLabel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
container.add(infoLabel);
|
||||
|
||||
eventLabel = new JLabel();
|
||||
eventLabel.setPreferredSize(new Dimension(fullWidth, BUTTON_HEIGHT));
|
||||
eventLabel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
container.add(eventLabel);
|
||||
|
||||
frame.validate();
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
this.currentPlayer = board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() == this.resetButton) {
|
||||
this.board.flush();
|
||||
displayBoard();
|
||||
this.currentPlayer = this.board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
if (!(this.board.won() || this.board.isFull())) {
|
||||
for (int i = 0; i < this.dropButtons.length; i++) {
|
||||
if (e.getSource() == this.dropButtons[i]) {
|
||||
if (dropObject(i)) {
|
||||
displayBoard();
|
||||
if (this.board.won()) {
|
||||
GameObject winnerObject = this.board.get(i, this.board.getTopObject(i));
|
||||
displayMessage(((Token)winnerObject).getOwner() + " won.");
|
||||
} else {
|
||||
triggerEvents();
|
||||
if (board.isFull()) {
|
||||
displayMessage("It's a draw");
|
||||
} else {
|
||||
this.currentPlayer = board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
displayMessage("That column is full.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void triggerEvents() {
|
||||
if (bomb.rollDie(this.board, 2)) {
|
||||
eventLabel.setText(bomb.announcement());
|
||||
displayBoard();
|
||||
} else if (block.rollDie(this.board, 1)) {
|
||||
eventLabel.setText(block.announcement());
|
||||
displayBoard();
|
||||
} else {
|
||||
eventLabel.setText("");
|
||||
}
|
||||
}
|
||||
}
|
151
src/interfaces/TicTacToeGUI.java
Normal file
151
src/interfaces/TicTacToeGUI.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package interfaces;
|
||||
|
||||
import board.Board;
|
||||
import events.IWinCondition;
|
||||
import events.ThreeInARow;
|
||||
import objects.Empty;
|
||||
import objects.GameObject;
|
||||
import objects.Player;
|
||||
import objects.Token;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TicTacToeGUI extends GUI {
|
||||
private JButton[] gameGrid = new JButton[9];
|
||||
|
||||
public TicTacToeGUI() {
|
||||
List<IWinCondition> conditions = new ArrayList<>();
|
||||
conditions.add(new ThreeInARow());
|
||||
this.board = new Board(3,3, new Empty(), conditions);
|
||||
int playerNum = 2;
|
||||
for (int i = 0; i < playerNum; i++) {
|
||||
String playerName = "";
|
||||
while (playerName.equals("")) {
|
||||
playerName = JOptionPane.showInputDialog(String.format("Name of player %d: ", i+1));
|
||||
if (playerName == null) {
|
||||
System.exit(0);
|
||||
}
|
||||
if (playerName.length() > 10) {
|
||||
JOptionPane.showMessageDialog(null, "Player name can't be longer than 10 characters.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
playerName = "";
|
||||
}
|
||||
}
|
||||
Player player;
|
||||
if (i == 1) {
|
||||
player = new Player(playerName, Color.BLACK);
|
||||
} else {
|
||||
player = new Player(playerName, Color.WHITE);
|
||||
}
|
||||
if (!this.board.addPlayer(player)) {
|
||||
JOptionPane.showMessageDialog(null, "Player is not unique. Please try again.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
JFrame frame = new JFrame("Four in a row");
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
int fullWidth = (BUTTON_WIDTH) * 3;
|
||||
int fullHeight = (TILE_HEIGHT) * 3;
|
||||
|
||||
this.frame = frame;
|
||||
JPanel container = new JPanel();
|
||||
container.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
|
||||
container.setPreferredSize(new Dimension(fullWidth, fullHeight + 2 * BUTTON_HEIGHT));
|
||||
frame.add(container);
|
||||
|
||||
JPanel panel2 = new JPanel();
|
||||
this.mainPanel = panel2;
|
||||
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
|
||||
panel2.setPreferredSize(new Dimension(fullWidth, fullHeight));
|
||||
readTiles();
|
||||
container.add(panel2);
|
||||
|
||||
infoLabel = new JLabel();
|
||||
infoLabel.setPreferredSize(new Dimension(fullWidth, 15));
|
||||
infoLabel.setBorder(new EmptyBorder(10, 10, 15, 10));
|
||||
container.add(infoLabel);
|
||||
this.resetButton = new JButton("Reset");
|
||||
this.resetButton.addActionListener(this);
|
||||
container.add(this.resetButton);
|
||||
|
||||
frame.validate();
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
currentPlayer = board.nextPlayer();
|
||||
displayMessage("It's " + currentPlayer + "'s turn.");
|
||||
}
|
||||
|
||||
public void displayBoard() {
|
||||
for (JButton button : this.gameGrid) {
|
||||
this.mainPanel.remove(button);
|
||||
}
|
||||
this.gameGrid = new JButton[this.board.getWidth() * this.board.getHeight()];
|
||||
readTiles();
|
||||
this.frame.validate();
|
||||
}
|
||||
|
||||
void readTiles() {
|
||||
int k = 0;
|
||||
for (int i = 0; i < board.getHeight(); i++) {
|
||||
for (int j = 0; j < board.getWidth(); j++) {
|
||||
JButton button = new JButton();
|
||||
button.addActionListener(this);
|
||||
GameObject obj = board.get(j,i);
|
||||
if (obj.getColor() == Color.black) {
|
||||
button.setText("X");
|
||||
} else if (obj.getColor() == Color.white) {
|
||||
button.setText("O");
|
||||
}
|
||||
button.setPreferredSize(new Dimension(BUTTON_WIDTH, TILE_HEIGHT));
|
||||
this.gameGrid[k++] = button;
|
||||
mainPanel.add(button, BorderLayout.PAGE_START);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() == this.resetButton) {
|
||||
this.board.flush();
|
||||
displayBoard();
|
||||
this.currentPlayer = this.board.nextPlayer();
|
||||
displayMessage("It's " + this.currentPlayer + "'s turn.");
|
||||
}
|
||||
if (!(board.won() || board.isFull())) {
|
||||
for (int i = 0; i < this.gameGrid.length; i++) {
|
||||
if (e.getSource() == this.gameGrid[i]) {
|
||||
if (this.gameGrid[i].getText().equals("")) {
|
||||
int x = i % 3;
|
||||
int y = i / 3;
|
||||
this.board.set(x, y, new Token(currentPlayer));
|
||||
displayBoard();
|
||||
if (!board.won()) {
|
||||
currentPlayer = board.nextPlayer();
|
||||
displayMessage("It's " + currentPlayer + "'s turn.");
|
||||
} else {
|
||||
GameObject winnerObject = board.get(x, board.getTopObject(x));
|
||||
displayMessage(((Token)winnerObject).getOwner() + " won.");
|
||||
}
|
||||
if (board.isFull()) {
|
||||
displayMessage("It's a draw");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
src/objects/Empty.java
Normal file
3
src/objects/Empty.java
Normal file
@@ -0,0 +1,3 @@
|
||||
package objects;
|
||||
|
||||
public class Empty extends GameObject {}
|
11
src/objects/GameObject.java
Normal file
11
src/objects/GameObject.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package objects;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class GameObject {
|
||||
Color color = Color.LIGHT_GRAY;
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
}
|
9
src/objects/Immovable.java
Normal file
9
src/objects/Immovable.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package objects;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class Immovable extends GameObject {
|
||||
public Immovable() {
|
||||
this.color = Color.BLACK;
|
||||
}
|
||||
}
|
38
src/objects/Player.java
Normal file
38
src/objects/Player.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package objects;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Player {
|
||||
private final String name;
|
||||
private final Color color;
|
||||
|
||||
public Player(String name, Color color) {
|
||||
this.name = name;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Player player = (Player) o;
|
||||
return Objects.equals(name, player.name) ||
|
||||
Objects.equals(color, player.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(name, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
14
src/objects/Token.java
Normal file
14
src/objects/Token.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package objects;
|
||||
|
||||
public class Token extends GameObject {
|
||||
private final Player owner;
|
||||
|
||||
public Token(Player owner) {
|
||||
this.owner = owner;
|
||||
this.color = owner.getColor();
|
||||
}
|
||||
|
||||
public Player getOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user