This I have written as part of my LLD Practice. Please let me know further imporvements that can be done.
Also tell is current design is Strong/Average/Lean Hire??
/*
Standard Snake Ladder Game
- Players can only start if they get 1 on dice
- On getting 6 they can take one more chance
- Design Patterns Used:
- Singelton for Board
- Strategy for dice/board
- Observer for game updates
*/import javax.swing.text.Position;
import java.util.*;
enum PieceColor{
Red, Green, Yellow, Blue
}
class Player{
String id;
String name;
PieceColor pieceColor;
boolean firstChance;
Player(String name, PieceColor pieceColor){
this.id=UUID.randomUUID().toString();
this.name=name;
this.pieceColor=pieceColor;
this.firstChance=true;
}
void setFirstChance(boolean flag){
this.firstChance=flag;
}
}
class Cell{
int cellNo;
int jumpTo;
Cell(int cellNo){
this.cellNo=cellNo;
this.jumpTo=-1;
}
boolean hasJump(){
return this.jumpTo!=-1;
}
}
interface BoardStrategy{
void configureBoard(Map<Integer,Cell> board);
}
class RandomBoardStrategy implements BoardStrategy{
@Override
public void configureBoard(Map<Integer, Cell> board) {
//snake
board.get(40).jumpTo=10;
board.get(80).jumpTo=30;
board.get(90).jumpTo=20;
//ladder
//snake
board.get(30).jumpTo=60;
board.get(20).jumpTo=70;
board.get(10).jumpTo=80;
}
}
class Board{
static Board instance;
int size=100;
Map<Integer,Cell> board;
BoardStrategy boardStrategy;
Board(BoardStrategy boardStrategy){
this.board=new HashMap<>();
this.boardStrategy=boardStrategy;
for(int i=1;i<=size;i++){
board.put(i,new Cell(i));
}
this.boardStrategy.configureBoard(board);
}
int getJump(int pos){
Cell cell=board.get(pos);
return (cell.hasJump()) ? cell.jumpTo : pos;
}
}
interface DiceStrategy{
int roll(int face);
}
class StandardDiceStrategy implements DiceStrategy{
Random rand=new Random();
@Override
public int roll(int face) {
return rand.nextInt(face)+1;
}
}
class Dice{
int face;
DiceStrategy diceStrategy;
Dice(int face, DiceStrategy diceStrategy){
this.face=face;
this.diceStrategy=diceStrategy;
}
int roll(){
return diceStrategy.roll(face);
}
}
class Game{
Board board;
Dice dice;
Queue<Player> playersQueue;
Map<Player, Integer> playerPositionMap;
boolean isGameOver;
Game(List<Player> playerList, int face, DiceStrategy diceStrategy, BoardStrategy boardStrategy){
this.dice=new Dice(face,diceStrategy);
this.board=new Board(boardStrategy);
this.playersQueue=new LinkedList<>();
this.playerPositionMap=new HashMap<>();
for(Player player:playerList){
playersQueue.add(player);
playerPositionMap.put(player,0); //start off board
}
this.isGameOver=false;
}
//player can only start when he gets 1 and can get extra chance when he get 6
void play(){
Scanner sc=new Scanner(System.in);
while(true){
if(this.isGameOver) break;
Player player=playersQueue.peek();
System.out.println(player.name+ "Hit Enter to Roll Dice:");
sc.nextLine();
int diceRoll=dice.roll();
if(player.firstChance){
if(diceRoll!=1){
//move back to queue, cant proceed
rotateTurn();
continue;
}
else{
player.firstChance=false;
playerPositionMap.put(player,1);
rotateTurn();
continue;
}
}
int currPos=playerPositionMap.get(player);
int nextPos=diceRoll+currPos;
if(nextPos>board.size){
playersQueue.add(player);
continue;
}
int finalJump=board.getJump(nextPos);
playerPositionMap.put(player,finalJump);
if(finalJump== board.size) {
System.out.println(player.name + " wins");
this.isGameOver=true;
continue;
}
if(diceRoll!=6){
rotateTurn();
}
}
}
void rotateTurn(){
Player p=playersQueue.poll();
playersQueue.add(p);
}
}
public class SnakeLadder {
public static void main(String[] args) {
Player p1=new Player("Nikhil",PieceColor.Green);
Player p2=new Player("Mukul",PieceColor.Red);
Player p3=new Player("Taran",PieceColor.Blue);
List<Player> players=new ArrayList<>();
players.add(p1);
players.add(p2);
players.add(p3);
Game game=new Game(players,6,new StandardDiceStrategy(),new RandomBoardStrategy());
game.play(); //entry point
}
}