public bool IsValid(Game game)
 {
     var koma = game.komas[k];
     if (game.gamestate == GameState.over) throw new Exception("already over");
     switch (koma.state)
     {
         case KomaState.MochiA:
             if (game.gamestate != GameState.turnA || state != TeState.Utsu) return false;
             break;
         case KomaState.OnA:
             if (game.gamestate != GameState.turnA || state != TeState.Move) return false;
             break;
         case KomaState.MochiB:
             if (game.gamestate != GameState.turnB || state != TeState.Utsu) return false;
             break;
         case KomaState.OnB:
             if (game.gamestate != GameState.turnB || state != TeState.Move) return false;
             break;
     }
     switch (state)
     {
         case TeState.Move:
             return koma.CanMove(X, Y);
         case TeState.Utsu:
             return koma.CanUtsu(X, Y);
         default:
             throw new Exception("error");
     }
 }
 public void Go(Game game)
 {
     var koma = game.komas[k];
     switch (state)
     {
         case TeState.Move:
             koma.Move(X, Y);
             break;
         case TeState.Utsu:
             koma.Utsu(X, Y);
             break;
     }
     game.Next();
 }
 public Koma Clone(Game game)
 {
     Koma k = (Koma)MemberwiseClone();
     k.game = game;
     return k;
 }
 public Koma(int X, int Y, KomaState state, int index, Game game)
 {
     this.X = X; this.Y = Y; this.state = state; this.index = index; this.game = game;
     canbeH = canbeK = canbeZ = canbeL = true;
     only = isNari = false;
 }
 public Game Clone()
 {
     Game game = new Game();
     game.gamestate = gamestate;
     Dictionary<Koma, Koma> dict = new Dictionary<Koma, Koma>();
     for (int i = 0; i < 8; i++) dict.Add(komas[i], komas[i].Clone(game));
     for (int x = 0; x < 3; x++) for (int y = 0; y < 4; y++) if (onboards[x, y] != null) game.onboards[x, y] = dict[onboards[x, y]];
     for (int i = 0; i < 4; i++) game.motoas[i] = dict[motoas[i]];
     for (int i = 0; i < 4; i++) game.motobs[i] = dict[motobs[i]];
     for (int i = 0; i < 8; i++) game.komas[i] = dict[komas[i]];
     game.mochias = mochias.ConvertAll(k => dict[k]);
     game.mochibs = mochibs.ConvertAll(k => dict[k]);
     return game;
 }
        public static int Check(Te te, Game game, int depth)
        {
            te.Go(game);
            if (game.gamestate == GameState.over)
            {
                return big;
            }
            if (depth >= 1)
            {
                List<Koma> mochi = game.gamestate == GameState.turnB ? game.mochias : game.mochibs;
                int res = 0;
                foreach (var k in mochi) res += Point(k);
                foreach (var k in game.onboards)
                {
                    if (k == null) continue;
                    if (k.state == ((game.gamestate == GameState.turnB) ? KomaState.OnA : KomaState.OnB))
                    {
                        res += Point(k);
                    }
                }
                return res;
            }

            int ans = big;

            var aitete = game.PossTe();

            if (depth > 0)
            {
                int c = 0; Te aitete0 = new Te();
                foreach (var te2 in aitete)
                {
                    int d = Check(te2, game.Clone(), big);
                    if (c < d) { c = d; aitete0 = te2; }
                }
                aitete.Clear(); aitete.Add(aitete0);
            }

            foreach (var te2 in aitete)
            {
                int res = 0;
                Game game2 = game.Clone();
                te2.Go(game2);
                if (game2.gamestate == GameState.over) { ans = 0; continue; }
                var jibunte = game2.PossTe();

                if (depth == 1)
                {
                    int c = 0; Te jibunte0 = new Te();
                    foreach (var te3 in jibunte)
                    {
                        int d = Check(te3, game2.Clone(), big);
                        if (c < d) { c = d; jibunte0 = te3; }
                    }
                    jibunte.Clear(); jibunte.Add(jibunte0);
                }
                res = 0;
                foreach (var te3 in jibunte)
                {
                    int c = Check(te3, game2.Clone(), depth + 1);
                    if (res < c) { res = c; }
                }
                ans = Math.Min(ans, res);
            }
            return ans;
        }