//to end the current turn public void next() { if (single) { f.Show(); f.Refresh(); State news = new State(); for (int i = 0; i < 16; i++) { int owner = pcs[i].owner; if (owner == 0) { news.state[i, 0] = -1; news.state[i, 1] = -1; news.state[i, 2] = -1; } else { news.state[i, 0] = pcs[i].x; news.state[i, 1] = pcs[i].y; news.state[i, 2] = pcs[i].king ? 1 : 0; } } State final = State.getNextStep(news, form.dif); if (final == null) form.endSingle(); move(final); f.Hide(); cont = 0; if (checkLose(1)) { form.endSingle(); } } else { if (turn == 1) { turn = 2; form.label1.Text = "Black's Turn"; } else { form.label1.Text = "Yellow's Turn"; turn = 1; } cont = 0; } }
public bool checkLose(int player) { bool lose = true; foreach (Piece p in pcs) { if (p.owner == player) lose = false; } State news = new State(); for (int i = 0; i < 16; i++) { int owner = pcs[i].owner; if (owner == 0) { news.state[i, 0] = -1; news.state[i, 1] = -1; news.state[i, 2] = -1; } else { news.state[i, 0] = pcs[i].x; news.state[i, 1] = pcs[i].y; news.state[i, 2] = pcs[i].king ? 1 : 0; } } List<State> check = new List<State>(); for (int i = (player - 1) * 8; i < (player - 1) * 8 + 8; i++) { news.addStep(i, check, false); } if (check.Count == 0) { lose = true; } return lose; }
public void move(State s) { for (int i = 8; i < 16; i++) { if (pcs[i].owner == 2 && (pcs[i].x != s.state[i, 0] || pcs[i].y != s.state[i, 1])) { toMove = i; } } newX = s.state[toMove, 0]; newY = s.state[toMove, 1]; if (s.jumped.Count == 0) { form.timer1.Interval = 100; mode = 1; time = 0; form.timer1.Start(); } else { form.timer1.Interval = 100; mode = 2; time = 0; where = 0; inter = s.jumped; newX = inter[0].x; newY = inter[0].y; form.timer1.Start(); } for (int i = 0; i < 16; i++) { if (pcs[i].owner != 0 && s.state[i, 0] == -1) { pcs[i].owner = 0; pcs[i].p.Enabled = false; pcs[i].p.Hide(); } if (!pcs[i].king && s.state[i, 2] == 1) pcs[i].kinged(); } }
//getNextStep determines the step the computer will make given the current status //of the board and the difficulty level public static State getNextStep(State s, int diff) { List<State> possible = new List<State>(); List<Tree> tree = new List<Tree>(); for (int i = 8; i < 16; i++) { s.addStep(i, possible, false); } foreach (State st in possible) { Tree fresh = new Tree(st); tree.Add(fresh); } //for different difficulty level(lvl3 is disabled due to memory constraint) switch (diff) { case 1: foreach (Tree t in tree) { t.populate(2); } break; case 2: foreach (Tree t in tree) { t.populate(4); } break; case 3: foreach (Tree t in tree) { t.populate(6); } break; default: break; } foreach (Tree t in tree) { t.calc(); } int max = -2000; int refer = 0; int num = 0; int c = 0; foreach (Tree t in tree) { if (t.value > max) { max = t.value; refer = num; } if (t.value == max) { c++; } num++; } if (c != 1) { num = 0; foreach (Tree t in tree) { if(t.value == max) { t.state.eval(); if (t.state.value > max) { max = t.state.value; refer = num; } } num++; } } if (possible.Count == 0) return null; //find the most yielding step and return its state return possible[refer]; }
//addStep adds all the possible states that can be derived from the current state when moving the piece i //into a predefined List dest public void addStep(int i, List<State> dest, bool done) { //done is if the piece had made a move in this turn, done will prevent the piece from making a non-eating move bool yellow = i < 8; if (state[i, 0] == -1) return; //invalid piece if(state[i, 2] == 0 && yellow) { //yellow player moving yellow piece int locr = find(state[i, 0] + 1, state[i, 1] + 1); //the two pieces that a non-king piece can move to without eating other pieces int locl = find(state[i, 0] - 1, state[i, 1] + 1); //if the right spot is empty if(locr == -1 && !done) { State next = new State(this); next.state[i, 0]++; next.state[i, 1]++; if(next.state[i, 1] == 7) next.state[i, 2] = 1; dest.Add(next); }else if(locr > 7) { //if the piece next to it is black int endp = find(state[i, 0] + 2, state[i, 1] + 2); if(endp == -1) { //if the destination is empty State next = new State(this); next.state[locr, 0] = -1; next.state[locr, 1] = -1; next.state[i, 0] += 2; next.state[i, 1] += 2; next.jumped = new List<coor>(); foreach (coor c in this.jumped) { next.jumped.Add(c); } next.jumped.Add(new coor(state[i, 0] + 2, state[i, 1] + 2)); if(next.state[i, 1] == 7) next.state[i, 2] = 1; dest.Add(next); next.addStep(i, dest, true); } } //if the left spot is empty if(locl == -1 && !done) { State next = new State(this); next.state[i, 0]--; next.state[i, 1]++; if(next.state[i, 1] == 7) next.state[i, 2] = 1; dest.Add(next); //if the left spot is black }else if(locl > 7) { int endp = find(state[i, 0] - 2, state[i, 1] + 2); if(endp == -1) { State next = new State(this); next.state[locl, 0] = -1; next.state[locl, 1] = -1; next.state[i, 0] -= 2; next.state[i, 1] += 2; next.jumped = new List<coor>(); foreach (coor c in this.jumped) { next.jumped.Add(c); } next.jumped.Add(new coor(state[i, 0] - 2, state[i, 1] + 2)); if(next.state[i, 1] == 7) next.state[i, 2] = 1; dest.Add(next); next.addStep(i, dest, true); } } //when it's black's turn }else if(state[i, 2] == 0 && !yellow) { int locr = find(state[i, 0] + 1, state[i, 1] - 1); int locl = find(state[i, 0] - 1, state[i, 1] - 1); if(locr == -1 && !done) { State next = new State(this); next.state[i, 0]++; next.state[i, 1]--; if (next.state[i, 1] == 0) next.state[i, 2] = 1; dest.Add(next); }else if(locr <= 7 && locr != -1) { int endp = find(state[i, 0] + 2, state[i, 1] - 2); if(endp == -1) { State next = new State(this); next.state[locr, 0] = -1; next.state[locr, 1] = -1; next.state[i, 0] += 2; next.state[i, 1] -= 2; next.jumped = new List<coor>(); foreach (coor c in this.jumped) { next.jumped.Add(c); } next.jumped.Add(new coor(state[i, 0] + 2, state[i, 1] - 2)); if(next.state[i, 1] == 0) next.state[i, 2] = 1; dest.Add(next); next.addStep(i, dest, true); } } //left empty if(locl == -1 && !done) { State next = new State(this); next.state[i, 0]--; next.state[i, 1]--; if(next.state[i, 1] == 0) next.state[i, 2] = 1; dest.Add(next); } //left yellow else if (locl <= 7 && locl != -1) { int endp = find(state[i, 0] - 2, state[i, 1] - 2); if(endp == -1) { State next = new State(this); next.state[locl, 0] = -1; next.state[locl, 1] = -1; next.state[i, 0] -= 2; next.state[i, 1] -= 2; next.jumped = new List<coor>(); foreach (coor c in this.jumped) { next.jumped.Add(c); } next.jumped.Add(new coor(state[i, 0] - 2, state[i, 1] - 2)); if(next.state[i, 1] == 0) next.state[i, 2] = 1; dest.Add(next); next.addStep(i, dest, true); } } //if piece is king }else if(state[i, 2] == 1) { int[] loc = new int[4]; loc[0] = find(state[i, 0] + 1, state[i, 1] - 1); loc[1] = find(state[i, 0] - 1, state[i, 1] - 1); loc[3] = find(state[i, 0] - 1, state[i, 1] + 1); loc[2] = find(state[i, 0] + 1, state[i, 1] + 1); for(int j = 0; j < 4; j++) { int x = j % 2 == 0 ? 1 : -1; int y = j < 2 ? -1 : 1; if(loc[j] == -1 && !done) { State next = new State(this); next.state[i, 0] += x; next.state[i, 1] += y; dest.Add(next); }else if((loc[j] > 7 && yellow) || (loc[j] <= 7 && !yellow && loc[j] != -1)) { int endp = find(state[i, 0] + 2 * x, state[i, 1] + 2 * y); if(endp == -1) { State next = new State(this); next.state[loc[j], 0] = -1; next.state[loc[j], 1] = -1; next.state[i, 0] += 2 * x; next.state[i, 1] += 2 * y; next.jumped = new List<coor>(); foreach (coor c in this.jumped) { next.jumped.Add(c); } next.jumped.Add(new coor(state[i, 0] + 2 * x, state[i, 1] + 2 * y)); dest.Add(next); next.addStep(i, dest, true); } } } } }
//copy constructor public State(State another) { state = new int[16,3]; for(int i = 0; i < 16; i++) { state[i,0] = another.state[i, 0]; state[i,1] = another.state[i, 1]; state[i,2] = another.state[i, 2]; } //reset the list of pieces jumped this.jumped = new List<coor>(); }
public Tree(State s) { state = new State(s); next = new List<Tree>(); height = 1; value = -1001; }