public static List <RecRateResult> recRate(State2048 root, int depth) { List <StateTrans> moves = root.getAllMoveStates(); //If we can't move, the game is over; worst penalty if (moves.Count == 0) { return new List <RecRateResult> { new RecRateResult(double.MaxValue, MoveDir.Self) } } ; //If the depth is zero, return the result from this state if (depth == 0) { return new List <RecRateResult> { new RecRateResult(root.rate(), MoveDir.Self) } } ; List <RecRateResult> result = new List <RecRateResult>(); foreach (StateTrans st in moves) { double bestOfWorst = double.MaxValue; List <State2048> allRandom = st.state.getAllRandom(); foreach (State2048 rand in allRandom) { List <RecRateResult> randRes = recRate(rand, depth - 1); //Take the maximum penalty double worstRate = randRes[0].rating; for (int i = 1; i < randRes.Count; i++) { if (randRes[i].rating > worstRate) { worstRate = randRes[i].rating; } } if (worstRate < bestOfWorst) { bestOfWorst = worstRate; } } result.Add(new RecRateResult(bestOfWorst, st.dir)); } return(result); }
//Copy constructor public State2048(State2048 s) { this.rows = s.rows; this.cols = s.cols; this.grid = new int[rows, cols]; for (int r = 0; r < this.rows; r++) { for (int c = 0; c < this.cols; c++) { this.grid[r, c] = s.grid[r, c]; } } }
public static double alphabetarate(State2048 root, int depth, double alpha, double beta, bool player) { if (depth == 0) { return(root.rate()); } if (player) { List <StateTrans> moves = root.getAllMoveStates(); //If we can't move, the game is over; worst penalty if (moves.Count == 0) { return(double.MaxValue); } foreach (StateTrans st in moves) { alpha = Math.Min(alpha, alphabetarate(st.state, depth - 1, alpha, beta, !player)); if (beta >= alpha) { break; } } return(alpha); } else { List <State2048> moves = root.getAllRandom(); foreach (State2048 st in moves) { beta = Math.Max(beta, alphabetarate(st, depth - 1, alpha, beta, !player)); if (beta <= alpha) { break; } } return(beta); } }
public List <State2048> getAllRandom() { List <State2048> res = new List <State2048>(); List <Tuple <int, int> > free = this.getFree(); foreach (Tuple <int, int> x in free) { State2048 next; next = new State2048(this); next.grid[x.Item1, x.Item2] = 1; res.Add(next); next = new State2048(this); next.grid[x.Item1, x.Item2] = 2; res.Add(next); } return(res); }
public bool equalTo(State2048 alt) { if (this.rows != alt.rows) { return(false); } if (this.cols != alt.cols) { return(false); } for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { if (this.grid[r, c] != alt.grid[r, c]) { return(false); } } } return(true); }
public List <StateTrans> getAllMoveStates() { List <StateTrans> allMoves = new List <StateTrans>(); State2048 next; next = new State2048(this); next.pushLeft(); if (!this.equalTo(next)) { allMoves.Add(new StateTrans(next, MoveDir.Left)); } next = new State2048(this); next.pushRight(); if (!this.equalTo(next)) { allMoves.Add(new StateTrans(next, MoveDir.Right)); } next = new State2048(this); next.pushUp(); if (!this.equalTo(next)) { allMoves.Add(new StateTrans(next, MoveDir.Up)); } next = new State2048(this); next.pushDown(); if (!this.equalTo(next)) { allMoves.Add(new StateTrans(next, MoveDir.Down)); } return(allMoves); }
public StateTrans(State2048 state, MoveDir dir) { this.dir = dir; this.state = state; }