Example #1
0
 static void waitAndUpdate(Draw draw, GameManager game, int wait, int state, List<bool> isBurst = null, List<Card> cantPutCard = null)
 {
     DX.ClearDrawScreen();
     if (state >= 0)
     {
         draw.DrawGrid();
         draw.DrawFieldCard(game);
         draw.DrawHandCard(game, -1, new Point());
         draw.DrawState(game);
         draw.DrawBurst(game, isBurst);
     }
     DX.ScreenFlip();
     DX.WaitVSync(wait);
 }
Example #2
0
        //プレイヤーの状態描画
        public void DrawState(GameManager game)
        {
            //山札枚数
            //1P
            uint deckCol = DX.GetColor(255, 255, 255);
            Point deck_1P = new Point(GridStart.X / 2 - cardScale.Width / 2, screenSize.Height - (int)(grid_len * 2) - cardScale.Height);
            string decknum_1P = game.deck[0].Count().ToString();
            int decknumLen_1P = DX.GetDrawStringWidth(decknum_1P, decknum_1P.Length);
            DX.DrawBox(deck_1P.X, deck_1P.Y, deck_1P.X + cardScale.Width, deck_1P.Y + cardScale.Height, deckCol, 1);
            DX.DrawString(deck_1P.X + cardScale.Width / 2 - decknumLen_1P / 2, deck_1P.Y + cardScale.Height / 2- DX.GetFontSize()/2, decknum_1P, DX.GetColor(0, 0, 0));
            //2P
            Point deck_2P = new Point(screenSize.Width/2 + (GridStart.X + (int)(grid_len * fieldSize.Width)) / 2 - cardScale.Width / 2,
                 (int)(grid_len));
            string decknum_2P = game.deck[1].Count().ToString();
            int decknumLen_2P = DX.GetDrawStringWidth(decknum_2P, decknum_2P.Length);
            DX.DrawBox(deck_2P.X, deck_2P.Y, deck_2P.X + cardScale.Width, deck_2P.Y + cardScale.Height, deckCol, 1);
            DX.DrawString(deck_2P.X + cardScale.Width / 2 - decknumLen_2P / 2, deck_2P.Y + cardScale.Height / 2 - DX.GetFontSize() / 2, decknum_2P, DX.GetColor(0, 0, 0));

            //現在のプレイヤー表示
            string msg = (game.now_Player + 1) + "Pの番です";
            int msg_len = DX.GetDrawStringWidth(msg, msg.Length);
            DX.DrawString(deck_2P.X - msg_len / 2, screenSize.Height / 2, msg, DX.GetColor(0, 255 * (game.is1P ? 1 : 0), 255 * (game.now_Player)));

            //メッセージ表示
            int showMessage = 4;
            Point msgPt = new Point(GridStart.X + (int)(grid_len * (fieldSize.Width + 1)), deck_2P.Y + cardScale.Height+ DX.GetFontSize());
            DX.DrawBox(msgPt.X, msgPt.Y, msgPt.X + DX.GetFontSize() * 8, msgPt.Y + DX.GetFontSize() * showMessage, DX.GetColor(128, 128, 128), 1);
            foreach(var elem in game.messageList.Reverse<string>().Take(showMessage).Select((v,i) => new { v, i }))
            {
                bool is1PDoc = elem.v.Contains("1P:");
                DX.DrawString(msgPt.X, msgPt.Y + DX.GetFontSize() * elem.i,
                    elem.v,
                    DX.GetColor(0, 255 * (is1PDoc ? 1 : 0), 255 * (is1PDoc ? 0 : 1)));
            }

            //イニシエーション
            string init_1p = "1Pinit:" + (game.initiation[0] ? "可" : "不可");
            string init_2p = "2Pinit:" + (game.initiation[1] ? "可" : "不可");
            string skill_1p = "1PSkill:" + game.skillPt_1p.ToString();
            string skill_2p = "2PSkill:" + game.skillPt_2p.ToString();
            int init_1p_len = DX.GetDrawStringWidth(init_1p, init_1p.Length);
            int init_2p_len = DX.GetDrawStringWidth(init_2p, init_2p.Length);
            int skill_1p_len = DX.GetDrawStringWidth(skill_1p, skill_1p.Length);
            int skill_2p_len = DX.GetDrawStringWidth(skill_2p, skill_2p.Length);
            DX.DrawString(GridStart.X / 2 - init_1p_len / 2, screenSize.Height / 2-40, init_1p, DX.GetColor(255, 255, 255));
            DX.DrawString(GridStart.X / 2 - init_2p_len / 2, screenSize.Height / 2- 20, init_2p, DX.GetColor(255, 255, 255));
            DX.DrawString(GridStart.X / 2 - skill_1p_len / 2, screenSize.Height / 2 + 20, skill_1p, DX.GetColor(255, 255, 255));
            DX.DrawString(GridStart.X / 2 - skill_2p_len / 2, screenSize.Height / 2 + 40, skill_2p, DX.GetColor(255, 255, 255));
        }
Example #3
0
        //CPUの再帰用コンストラクタ
        public GameManager(GameManager game, List<Card>[] handCard)
        {
            myConstractor(game.cardNum, game.handCardNum, game.fieldSize, game.cardSize);
            for(int x = 0; x < game.fieldSize.Width; x++)
            {
                for (int y = 0; y < game.fieldSize.Height; y++)
                {
                    field[x, y] = new Field(game.field[x, y]);
                }
            }
            initiation = (bool[])game.initiation.Clone();
            now_Player = game.now_Player;
            for(int i = 0; i < handCard.Count(); i++)
            {
                this.handCard[i] = new List<Card>(handCard[i]);
            }

        }
Example #4
0
        //init
        public Draw(GameManager game)
        {
            fieldSize = game.fieldSize;
            cardSize = game.cardSize;

            //グリッドの色
            LineCol = DX.GetColor(255, 255, 255);

            //グリッドの1マスのサイズ
            grid_len = screenSize.Height / (fieldSize.Height + 2);
            //グリッドの右上座標
            GridStart = new Point((int)(screenSize.Width / 2 - grid_len * fieldSize.Width / 2), (int)grid_len);

            //属性の色
            elementColDict = new Dictionary<int, uint>()
                {
                    {0,DX.GetColor(255,0,0) },{1,DX.GetColor(0,0,255)},{2,DX.GetColor(0,0,0) },{3,DX.GetColor(0,255,0) },{4,DX.GetColor(255,255,0) }
                };

            //カードの大きさ
            cardScale = new Size((int)(grid_len * cardSize.Width), (int)(grid_len * cardSize.Height));
        }
Example #5
0
        //バースト時のカード枚数取得
        public static int getSheetsNumber(GameManager game, int group)
        {
            int groupSum = 0;
            Size fieldSize = game.fieldSize;
            Size cardSize = game.cardSize;

            for (int x = 0; x < fieldSize.Width; x++)
            {
                for (int y = 0; y < fieldSize.Height; y++)
                {
                    if (game.field[x, y].group == group)
                        groupSum++;
                }
            }
            int cardProduct = cardSize.Width * cardSize.Height;
            int groupCardNum = groupSum / cardProduct;

            return groupCardNum;
        }
Example #6
0
        //バーストさせる
        public static int Burst(GameManager game, Size cardSize, int group)
        {
            int groupSum = 0;
            Size fieldSize = game.fieldSize;

            for (int x = 0; x < fieldSize.Width; x++)
            {
                for (int y = 0; y < fieldSize.Height; y++)
                {
                    if (game.field[x, y].group == group)
                    {
                        game.field[x, y] = new Field();
                        groupSum++;
                    }
                }
            }
            int cardProduct = cardSize.Width * cardSize.Height;
            int groupCardNum = groupSum / cardProduct;
            return groupCardNum;
        }
Example #7
0
        //バーストチェック
        public static bool isBurst(GameManager game, Size cardSize, int group)
        {
            Size fieldSize = game.fieldSize;

            Card card = new Card(group);
            for (int x = 0; x < fieldSize.Width; x++)
            {
                for (int y = 0; y < fieldSize.Height; y++)
                {
                    for (int turn = 0; turn < 2; turn++)
                    {
                        Size mycardSize = cardSize;
                        if (turn % 2 == 1)
                        {
                            mycardSize = new Size(cardSize.Height, cardSize.Width);
                        }
                        card.turn = turn;
                        if (canPut(game.field, new Point(x, y), card, mycardSize, group, game.initiation, true))
                        {
                            card.turn = 0;
                            return false;
                        }
                    }
                }
            }
            return true;
        }
Example #8
0
        static void Main(string[] args)
        {
            Size fieldSize = new Size(18, 24);
            Size cardSize = new Size(4, 6);
            int deckNum = 15;
            int handCardNum = 3;
            int wait = 60;
            bool isCPU = false;
            GameManager game = new GameManager(deckNum, handCardNum, fieldSize, cardSize);
            Draw draw = new Draw(game);
            CPU cpu = new CPU(0);

            DX.ChangeWindowMode(1);
            DX.DxLib_Init();
            DX.SetGraphMode(1280, 720, 32);
            DX.SetDrawScreen(DX.DX_SCREEN_BACK);

            //山札のロード
            Card.LoadDeck();

            //ゲームの状態
            int state = -1;
            //移動中の手札の番号
            int moving_hand_cur = -1;
            //前の人が詰んでいたか
            bool[] isAlreadyCheckmate = new bool[game.max_Player];
            int mouse_state = 0;
            int wheel;
            string[] deckIndexes = new string[game.max_Player];
            //置ける場所の候補
            List<Card> candidates = new List<Card>();

            while (DX.ScreenFlip() == 0 && DX.ProcessMessage() == 0 && DX.ClearDrawScreen() == 0)
            {
                Point mousePoint;
                int hand_cur = -1;
                mouse_state = getMouse(out mousePoint);
                if(mousePoint==new Point())
                {
                    //マウス座標
                    int mx = 0, my = 0;
                    DX.GetMousePoint(out mx, out my);
                    mousePoint = new Point(mx, my);
                }

                if (state >= 0)
                {
                    //描画
                    draw.DrawGrid();
                    draw.DrawFieldCard(game);
                    draw.DrawAssist(game, candidates, moving_hand_cur);
                    hand_cur = draw.DrawHandCard(game, moving_hand_cur, mousePoint);
                }

                switch (state)
                {
                    case -2://設定
                        wheel = DX.GetMouseWheelRotVol();
                        draw.DrawSetting(game, mousePoint, wheel, ref deckIndexes);
                        if (clickedLeft(ref mouse_state))
                            state = -1;
                        break;
                    case -1://タイトル
                        wheel = DX.GetMouseWheelRotVol();
                        if (wheel != 0) isCPU = !isCPU;
                        draw.DrawTitle(isCPU);
                        if (clickedLeft(ref mouse_state))
                            state = 0;
                        if (clickedRight(ref mouse_state))
                            state = -2;
                        break;
                    case 0://初期化
                        draw = new Draw(game);
                        game = new GameManager(deckNum, handCardNum, fieldSize, cardSize, deckIndexes);
                        if (isCPU) cpu = new CPU(1);
                        //置ける場所の候補取得
                        candidates = Field.getCandidates(game);
                        state = 1;
                        break;
                    case 1://手札選択
                        if (isCPU && game.now_Player == cpu.me)
                        {
                            state = 5;
                        }
                        if (clickedLeft(ref mouse_state) && hand_cur != -1 && game.nowHandCard[hand_cur].available)
                        {
                            moving_hand_cur = hand_cur;
                            state = 2;
                        }
                        break;
                    case 2://手札移動
                        Point fieldPt = draw.DrawMovingCard(game, moving_hand_cur, mousePoint);
                        bool clicked = clickedLeft(ref mouse_state);

                        //回転
                        wheel = DX.GetMouseWheelRotVol();
                        if (wheel > 0) game.nowHandCard[moving_hand_cur].turn = (game.nowHandCard[moving_hand_cur].turn + 1) % 4;
                        if (wheel < 0) game.nowHandCard[moving_hand_cur].turn = (game.nowHandCard[moving_hand_cur].turn + 3) % 4;

                        //フィールドに配置
                        if (clicked && fieldPt != new Point(-1,-1))
                        {
                            if (!game.handToField(fieldPt, moving_hand_cur))
                                break;
                            moving_hand_cur = -1;

                            //勝利判定
                            if (Enumerable.Range(0, game.max_Player).Select(player => game.deck[player].Count() + game.handCard[player].Count()).Count(allCards => allCards == 0) > 0)
                            {
                                state = 4;
                                break;
                            }

                            //手番交代
                            //waitAndUpdate(draw, game, wait, state);
                            game.next();

                            state = 3;
                            break;
                        }
                        //移動をやめる
                        if (clicked && hand_cur != -1)
                        {
                            moving_hand_cur = -1;
                            state = 1;
                        }
                        break;
                    case 3://詰み・バーストチェック

                        //バースト
                        bool[] isBurst = new bool[] { false, false };
                        for (int i = 0; i < game.max_Player; i++)
                        {
                            if (Field.isBurst(game, cardSize, i))
                            {
                                isBurst[i] = true;
                            }
                        }
                        if (isBurst.Count(t => t) != 0)
                        {
                            waitAndUpdate(draw, game, wait, state, isBurst: isBurst.ToList());
                        }
                        for (int i = 0; i < 2; i++)
                        {
                            if (isBurst[i])
                            {
                                game.burst(i);
                            }
                        }
                        if (isBurst.Count(t => t == true) != 0)
                        {
                            //手番を戻す
                            game.next();
                            game.insertInfo("バースト");
                            state = 1;
                        }

                        //ドロー
                        game.draw();
                        //詰み
                        candidates = Field.getCandidates(game);
                        if (candidates.Count() == 0)
                        {
                            if (isAlreadyCheckmate.Count(t => t) >= game.max_Player)
                            {
                                game.insertInfo("両詰み");
                                waitAndUpdate(draw, game, wait, state, isBurst: Enumerable.Range(0, game.max_Player).Select(t => true).ToList());
                                isAlreadyCheckmate = new bool[game.max_Player];
                                game.clearField();
                                //手番を戻す
                                game.next();
                                candidates = Field.getCandidates(game);
                                state = 1;
                            }
                            else
                            {
                                game.insertInfo("詰み");
                                isAlreadyCheckmate[game.now_Player] = true;
                                waitAndUpdate(draw, game, wait, state);
                                //手番を戻す
                                game.next();
                                state = 3;
                            }
                        }
                        else
                        {
                            isAlreadyCheckmate[game.now_Player] = false;
                            state = 1;
                        }
                        break;
                    case 4://勝利
                        draw.DrawWinnerMessage((game.now_Player + 1) + "P WIN!!!!");
                        if (clickedLeft(ref mouse_state))
                        {
                            state = -1;
                        }
                        break;
                    case 5://CPU選択

                        var cpu_res = cpu.choice(game);
                        int cardCur = game.nowHandCard.IndexOf(game.nowHandCard.Where(t => t.handCardID == cpu_res.card.handCardID).First());
                        //CPUの手の回転
                        game.handCard[game.now_Player][cardCur].turn = cpu_res.card.turn;
                        if (!game.handToField(cpu_res.card.point, cardCur))
                            throw new Exception("CPU fatal error");

                        //勝利判定
                        if (Enumerable.Range(0, game.max_Player).Select(player => game.deck[player].Count() + game.handCard[player].Count()).Count(allCards => allCards == 0) > 0)
                        {
                            state = 4;
                            break;
                        }

                        //手番交代
                        waitAndUpdate(draw, game, wait, state);
                        game.next();

                        state = 3;
                        break;

                }

                if (state >= 0)
                    draw.DrawState(game);
            }

            DX.DxLib_End();
        }
Example #9
0
        //バースト表示
        public void DrawBurst(GameManager game, List<bool> isBurst)
        {
            if (isBurst == null || isBurst.Count(t => t) == 0) return;

            List<int> burstNum = Enumerable.Range(0, isBurst.Count()).Where(t => isBurst[t]).ToList();

            for (int x = 0; x < fieldSize.Width; x++)
            {
                for (int y = 0; y < fieldSize.Height; y++)
                {
                    Card card = game.field[x, y].card;
                    if (card != null && burstNum.Contains(game.field[x, y].group))
                    {
                        Size mycardSize = new Size(game.cardSize.Width, game.cardSize.Height);
                        if (card.turn % 2 == 1) mycardSize = new Size(mycardSize.Height, mycardSize.Width);

                        DX.DrawBox(GridStart.X + (int)(grid_len * x), GridStart.Y + (int)(grid_len * y),
                            GridStart.X + (int)(grid_len * (x + mycardSize.Width)), GridStart.Y + (int)(grid_len * (y + mycardSize.Height)),
                            DX.GetColor(255, 0, 0), 1);
                    }
                }
            }
        }
Example #10
0
        //カード配置
        public static bool putCard(GameManager game, Point putAt, Card card, Size cardSize, bool[] initiation)
        {
            Field[,] field = game.field;
            Size fieldSize = game.fieldSize;
            int turn = card.turn;

            //カードサイズをターンにあわせる
            Size mycardSize = cardSize;
            if (turn % 2 == 1)
            {
                mycardSize = new Size(cardSize.Height, cardSize.Width);
            }

            //前回のイニシエーション保存
            bool[] oldInitiation = new bool[] { initiation[0], initiation[1] };

            //設置判定
            if (!canPut(field, putAt, card, mycardSize, game.now_Player, initiation)) return false;

            if (isLowBurst(game, putAt, card, mycardSize))
            {
                //イニシエーションの場合は取り消し
                int init_group = game.now_Player;
                if (initiation[init_group] != oldInitiation[init_group])
                    initiation[init_group] = true;
                return false;
            }

            //カード配置
            fillCard(game.field, putAt, card, mycardSize);

            return true;
        }
Example #11
0
        /// <summary>
        /// 手を選ぶ
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public resultSet choice(GameManager game)
        {
            cardSize = game.cardSize;
            GameManager newGame = new GameManager(game, game.handCard);
            superGame = game;
            int step = 1;
            //if (game.initiation[0] == true && game.initiation[1] == true) step = 4;
            resultSet[] bestPat = getScore(newGame, step: step);
            Console.WriteLine(string.Join("/", bestPat.Select(t => t.score.ToString())));

            return bestPat[game.now_Player];
        }
Example #12
0
        public void DrawSetting(GameManager game,Point mouse, int wheel, ref string[] deck)
        {
            if (DeckIndex == null || DeckIndex.Length != game.max_Player) DeckIndex = new int[game.max_Player];

            List<string> deckList = new List<string>() {"ランダム" };
            deckList.AddRange(Card.deckList.Keys);
            int fontSize = 32;
            int defaultFontSize = DX.GetFontSize();
            DX.SetFontSize(fontSize);
            Point settingStart = new Point(fieldSize.Width / 3, fieldSize.Height / 3);

            for(int i = 0; i < game.max_Player; i++)
            {
                DX.DrawString(settingStart.X, settingStart.Y + fontSize * 2 * i, (i + 1) + "Pデッキ", DX.GetColor(255, 255, 255));
                //デッキ情報の開始位置
                Point deck_start = new Point(settingStart.X, settingStart.Y + fontSize * (i * 2 + 1));

                deck[i] = deckList[DeckIndex[i]];

                //デッキ情報のサイズ
                Size deck_size = new Size(DX.GetDrawStringWidth(deck[i], deck[i].Length), fontSize);

                //move index
                if (mouse.X >= deck_start.X && mouse.X < deck_start.X + deck_size.Width &&
                    mouse.Y >= deck_start.Y && mouse.Y < deck_start.Y + deck_size.Height)
                {
                    if (wheel > 0) DeckIndex[i] = (DeckIndex[i] + 1) % deckList.Count();
                    if (wheel < 0) DeckIndex[i] = (DeckIndex[i] + deckList.Count() - 1) % deckList.Count();
                }

                //デッキ情報描画
                DX.DrawString(deck_start.X, deck_start.Y, deck[i], DX.GetColor(255, 0, 255));

                if (deck[i] == "ランダム")
                    deck[i] = "";
            }

            DX.SetFontSize(defaultFontSize);
        }
Example #13
0
        //フィールド上のカード描画
        public void DrawFieldCard(GameManager game)
        {
            for (int x = 0; x < fieldSize.Width; x++)
            {
                for (int y = 0; y < fieldSize.Height; y++)
                {
                    if (game.field[x, y].card != null)
                    {
                        DrawCard((int)(GridStart.X + grid_len * x), (int)(GridStart.Y + grid_len * y), game.field[x, y].card);
                    }
                    
                    //デバッグ用描画処理
                    /*
                    
                    if (game.field[x, y].group != -1)
                    {

                        DX.DrawBox((int)(GridStart.X + grid_len * x), (int)(GridStart.Y + grid_len * y),
                            (int)(GridStart.X + grid_len * (x + 1)), (int)(GridStart.Y + grid_len * (y + 1)),
                            game.field[x, y].group==0?DX.GetColor(0, 0, 0): DX.GetColor(255, 255, 255), 1);
                    }
                    if (game.field[x, y].connector != -1)
                    {
                        DX.DrawBox((int)(GridStart.X + grid_len * x), (int)(GridStart.Y + grid_len * y),
                            (int)(GridStart.X + grid_len * (x + 1)), (int)(GridStart.Y + grid_len * (y + 1)),
                            elementColDict[game.field[x, y].connector], 1);
                    }*/
                }
            }
        }
Example #14
0
        //移動中のカード描画
        public Point DrawMovingCard(GameManager game, int hand_cur, Point mouse)
        {
            bool is1P = game.is1P;
            Card card = game.nowHandCard[hand_cur];
            int x = 0, y = 0, fix_x = 0, fix_y = 0;
            Point fieldPt = new Point(-1, -1);

            //カードの中心座標を取得
            x = mouse.X - cardScale.Width / 2;
            y = mouse.Y - cardScale.Height / 2;
            fix_x = cardSize.Width - 1;
            fix_y = cardSize.Height - 1;
            if (card.turn % 2 == 1)
            {
                x = mouse.X - cardScale.Height / 2;
                y = mouse.Y - cardScale.Width / 2;
                fix_x = cardSize.Height - 1;
                fix_y = cardSize.Width - 1;
            }

            //グリッドにフィットさせる
            if (x >= GridStart.X && y >= GridStart.Y &&
                x < GridStart.X + grid_len * (fieldSize.Width - fix_x) && y < GridStart.Y + grid_len * (fieldSize.Height - fix_y))
            {
                fieldPt = new Point((int)((x - GridStart.X) / grid_len), (int)((y - GridStart.Y) / grid_len));
                x = fieldPt.X * (int)grid_len + GridStart.X;
                y = fieldPt.Y * (int)grid_len + GridStart.Y;
            }
            DrawCard(x, y, card);
            return fieldPt;

        }
Example #15
0
        //手札描画
        public int DrawHandCard(GameManager game, int hand_cur, Point mouse)
        {
            int cardOnMouseNum = -1;
            bool is1P = game.is1P;
            List<Card> card_1p = game.handCard[0];
            List<Card> card_2p = game.handCard[1];

            int handCard_width = GridStart.X / game.handCardNum;
            Size handCard_size = new Size(handCard_width, handCard_width / 2 * 3);

            Point HandCardStart_1P = new Point((int)(GridStart.X + grid_len * fieldSize.Width) + 1, (int)(GridStart.Y + grid_len * fieldSize.Height - handCard_size.Height));
            for (int i = 0; i < card_1p.Count(); i++)
            {
                int x = HandCardStart_1P.X + handCard_size.Width * i;
                int y=HandCardStart_1P.Y;

                if (is1P && mouse.X >= x && mouse.X < x + handCard_size.Width && mouse.Y >= y && mouse.Y < y + handCard_size.Height) cardOnMouseNum = i;
                if (is1P && i == hand_cur) continue;
                DrawCard(x, y, card_1p[i], handCard_size);
            }

            Point HandCardStart_2P = new Point(0, (int)grid_len);
            for (int i = 0; i < card_2p.Count(); i++)
            {
                int x = HandCardStart_2P.X + handCard_size.Width * i;
                int y = HandCardStart_2P.Y;
                if (!is1P && mouse.X >= x && mouse.X < x + handCard_size.Width && mouse.Y >= y && mouse.Y < y + handCard_size.Height) cardOnMouseNum = i;
                if (!is1P && i == hand_cur) continue;
                DrawCard(x, y, card_2p[i], handCard_size);
            }

            return cardOnMouseNum;
        }
Example #16
0
        //低バーストチェック
        public static bool isLowBurst(GameManager game, Point putAt, Card card, Size cardSize)
        {
            //一時的に埋める
            int tmpConnect = fillCard(game.field, putAt, card, cardSize);
            bool tmpInit = game.initiation[tmpConnect];
            game.initiation[tmpConnect] = false;

            for (int i = 0; i < game.max_Player; i++)
            {
                //バーストチェック
                if (!isBurst(game, cardSize, i))
                {
                    continue;
                }

                //バースト枚数取得
                int groupCardNum = getSheetsNumber(game, i);

                if (groupCardNum < 3)
                {
                    //埋めを解除
                    unfillCard(game.field, putAt, cardSize);

                    //判定コネクターを戻す
                    connector_group = tmpConnect;
                    game.initiation[tmpConnect] = tmpInit;
                    return true;
                }
            }
            //埋めを解除
            unfillCard(game.field, putAt, cardSize);

            //判定コネクターを戻す
            connector_group = tmpConnect;
            game.initiation[tmpConnect] = tmpInit;
            return false;
        }
Example #17
0
        /// <summary>
        /// 配置可能場所リスト生成
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public static List<Card> getCandidates(GameManager game)
        {
            //候補
            List<Card> candidates = new List<Card>();
            
            Size cardSize = game.cardSize;
            Size fieldSize = game.fieldSize;

            foreach (var card in game.nowHandCard)
            {
                if (card == null) continue;
                card.available = false;
                for (int x = 0; x < fieldSize.Width; x++)
                {
                    for (int y = 0; y < fieldSize.Height; y++)
                    {
                        for (int turn = 0; turn < 4; turn++)
                        {
                            Size mycardSize = cardSize;
                            if (turn % 2 == 1)
                            {
                                mycardSize = new Size(cardSize.Height, cardSize.Width);
                            }
                            card.turn = turn;
                            if (canPut(game.field, new Point(x, y), card, mycardSize, game.now_Player, game.initiation, true))
                            {
                                //低バーストでもない場合は候補に追加
                                if (!isLowBurst(game, new Point(x, y), card, mycardSize))
                                {
                                    Card cand = new Card(card);
                                    cand.point = new Point(x, y);
                                    candidates.Add(cand);
                                    card.available = true;
                                }
                            }
                        }
                    }
                }
                card.turn = 0;
            }

            return candidates;
        }
Example #18
0
        /// <summary>
        /// 再帰で最適解を求める
        /// </summary>
        /// <param name="game"></param>
        /// <param name="nest"></param>
        /// <param name="isMe"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        resultSet[] getScore(GameManager game, int nest = 0, int step = 1)
        {
            //手札がない
            if (game.handCard[game.now_Player].Count()==0)
            {
                return new resultSet[game.max_Player];
            }

            //手の候補取得
            List<Card> candidates = Field.getCandidates(game);
            
            Field[,] field = game.field;
            Size fieldSize = game.fieldSize;

            //候補のスコア
            List<resultSet[]> scores = new List<resultSet[]>();

            foreach (var card_vi in candidates.Select((v,i)=>new { v,i}))
            {
                Card card = card_vi.v;
                if (nest == 0 && game.now_Player == me)
                {
                    //パーセンテージを表示
                    Console.Write("{0, 4:f0}%", (double)(card_vi.i + 1) / candidates.Count() * 100);
                    Console.SetCursorPosition(0, Console.CursorTop);
                }
                if (card == null) continue;

                //カードサイズを回転に合わせる
                Size mycardSize = new Size(cardSize.Width, cardSize.Height);
                if (card.turn % 2 == 1) mycardSize = new Size(mycardSize.Height, mycardSize.Width);

                //コネクターグループ設置用
                List<bool> tmpInit = new List<bool>(game.initiation);
                if (!Field.canPut(game.field, card.point, card, mycardSize, game.now_Player, game.initiation))
                    throw new Exception("checkmate fatal error");

                //手札を減らす
                /*
                List<Card> innerHandCard = new List<Card>(myHandCard);
                var rmIndex = innerHandCard.IndexOf(innerHandCard.Where(t => t != null && t.handCardID == card.handCardID).First());
                innerHandCard[rmIndex] = null;*/
                List<Card>[] innerHandCard = game.handCard.Select(cards => cards.Select(t => t == null ? null : new Card(t)).ToList()).ToArray();
                var rmIndex = innerHandCard[game.now_Player].IndexOf(innerHandCard[game.now_Player].Where(t => t != null && t.handCardID == card.handCardID).First());
                innerHandCard[game.now_Player][rmIndex] = null;

                //フィールドに手札を置く
                GameManager innerGame = new GameManager(game, innerHandCard);
                int tmpConnect = Field.fillCard(innerGame.field, card.point, card, mycardSize);
                innerGame.next();

                resultSet[] cand = new resultSet[game.max_Player];
                for(int i = 0; i < game.max_Player; i++)
                {
                    cand[i] = new resultSet();
                }
                if (superGame.deck[game.now_Player].Count() == 0 && innerGame.handCard[game.now_Player].Count(t => t != null) == 0)
                {
                    //勝利の場合
                    cand[game.now_Player].score += 10000.0 - 1000.0 / (nest / game.max_Player + 1);
                }
                else if (Field.isBurst(innerGame, cardSize, tmpConnect))
                {
                    //バーストチェック
                    int burstNum = Field.Burst(innerGame, cardSize, tmpConnect);
                    cand[game.now_Player].score += (1000.0 + (burstNum - 3) * 10.0) - 100.0 / (nest / game.max_Player + 1);
                    innerGame.next();
                    var tmpcand = getScore(innerGame, nest: nest + 1, step: 1);
                    cand[game.now_Player].innerResult = tmpcand;
                    cand[game.now_Player].isBurst = true;
                }
                else
                {
                    //バーストしない場合再帰
                    int initCount = superGame.initiation.Count(t => t == true);
                    if (initCount == 0 || initCount == 1 && nest <= 1 || nest <= 0)
                        cand = getScore(innerGame, nest: nest + 1, step: 1);
                }
                //カード情報を候補に追加
                cand[game.now_Player].card = new Card(card);
                scores.Add(cand);

                //イニシエーション戻す
                game.initiation = new bool[game.max_Player];
                for (int i = 0; i < game.max_Player; i++)
                {
                    game.initiation[i] = tmpInit[i];
                }
            }

            //候補から最善手を予測
            var noPlayerRange = Enumerable.Range(0, game.max_Player).Where(player => player != game.now_Player);
            resultSet[] bestPattern = new resultSet[game.max_Player];
            if (scores.Count() > 0)
            {
                var scorePair = scores.Select(result => new { v = result, score = (result[game.now_Player].score / noPlayerRange.Select(player => result[player].score).Sum()) });
                var filtered = scorePair.Where(t => t.v[game.now_Player].innerResult == null ||
                    (!t.v[game.now_Player].innerResult[game.now_Player].isCheckmate && !t.v[game.now_Player].isCheckmate));
                //if (filtered.Count() == 0)
                {
                    bestPattern = scorePair.OrderByDescending(t => t.score).First().v;
                }
                /*else
                {
                    bestPattern = filtered.OrderByDescending(t => t.score).First().v;
                }*/
            }
            else
            {
                for (int i = 0; i < game.max_Player; i++)
                {
                    bestPattern[i] = new resultSet();
                }
            }

            //自分の手数を追加
            bestPattern[game.now_Player].score += candidates.Count();

            //詰みの場合ほかの人がボーナス
            if (nest != 0 && candidates.Count() == 0)
            {
                bestPattern[game.now_Player].isCheckmate = true;
                for (int i = 0; i < game.max_Player; i++)
                {
                    if (i == game.now_Player) continue;
                    bestPattern[i].score += 1000.0 - 100.0 / (nest / game.max_Player + 1);
                }
            }

            return bestPattern;
        }
Example #19
0
        //バーストチェック
        public static bool isBurst(GameManager game, Size cardSize, int group, List<int> ignoreGroup = null)
        {
            Size fieldSize = game.fieldSize;

            //最初の呼び出しは再帰に自分を含めない
            if (ignoreGroup == null) {
                ignoreGroup = new List<int>();
                ignoreGroup.Add(group);
            }

            Card card = new Card(group);
            for (int x = 0; x < fieldSize.Width; x++)
            {
                for (int y = 0; y < fieldSize.Height; y++)
                {
                    for (int turn = 0; turn < 2; turn++)
                    {
                        Size mycardSize = cardSize;
                        if (turn % 2 == 1)
                        {
                            mycardSize = new Size(cardSize.Height, cardSize.Width);
                        }
                        card.turn = turn;
                        if (canPut(game.field, new Point(x, y), card, mycardSize, group, game.initiation, true))
                        {
                            card.turn = 0;
                            return false;
                        }
                    }
                }
            }
            return true;
        }
Example #20
0
        //アシスト表示
        public void DrawAssist(GameManager game, List<Card> candidates, int handCardCur)
        {
            if (handCardCur < 0) return;
            foreach (var card in candidates)
            {
                if (card.handCardID != game.nowHandCard[handCardCur].handCardID
                    || card.turn != game.nowHandCard[handCardCur].turn)
                    continue;

                Size mycardSize = new Size(game.cardSize.Width, game.cardSize.Height);
                if (card.turn % 2 == 1) mycardSize = new Size(mycardSize.Height, mycardSize.Width);

                DX.DrawBox(GridStart.X + (int)(grid_len * card.point.X), GridStart.Y + (int)(grid_len * card.point.Y),
                    GridStart.X + (int)(grid_len * (card.point.X + mycardSize.Width)), GridStart.Y + (int)(grid_len * (card.point.Y + mycardSize.Height)),
                    DX.GetColor(0, 128, 0), 1);
            }
        }