コード例 #1
0
ファイル: Tetris.cs プロジェクト: 3587jjh/Tetris-Console
        void StartThread()
        {
            Message    msg = new Message(1, 1);
            Block      cur;
            BlockMaker rng  = new BlockMaker();
            Random     r    = new Random();
            int        hole = r.Next(0, W);

            Console.ResetColor();
            Console.Clear();
            DrawOutline1(f.backColor);
            DrawOutline2();
            rng.Init();
            UpdateDisplay();             // timeCnt = 0
            UpdateDisplay(false, -1);
            msg.StartCount();

            // 게임 스타트
            bool  wantNext  = true;          // 다음블럭을 가져올 것인가
            bool  holdUsed  = false;         // 게임에서 홀드가 한 번이라도 사용됐는가 (홀드창 블럭 유무)
            bool  canHold   = true;          // 현재 낙하 사이클에 홀드를 쓸 수 있는가 (연속은 금지됨)
            bool  curHeld   = false;         // 현재 블록에 대해 홀드를 작동 시켰는가
            Block hBlock    = new Block(1);  // 홀드된 블럭
            Block tmp       = new Block(1);  // cur과 hBlock을 swap하기 위한 임시 객체
            bool  gameOver  = false;
            bool  gameClear = false;

            nextTimer = 1;

            while (true)
            {
                if (wantNext)
                {
                    cur = rng.Next();
                }
                else
                {
                    cur = new Block(tmp.type);
                }
                f.Put(f.GetTrans(cur), false);
                f.Put(cur, false);

                while (true)                   // 현재 블록 cur이 놓일 때까지
                {
                    Thread A;
                    bool   isLockDelay = LockDelay(cur);
                    bool   recentMove  = false;
                    string recentS     = "";

                    if (isLockDelay)
                    {
                        A = new Thread(LockTimer);
                        lockTimerEnd[nextTimer] = false;
                    }
                    else
                    {
                        A = new Thread(DropTimer);
                        dropTimerEnd[nextTimer] = false;
                    }
                    A.Start();
                    while ((!isLockDelay && !dropTimerEnd[nextTimer]) ||
                           (isLockDelay && !lockTimerEnd[nextTimer]))
                    {
                        // 블록이 한 칸 떨어지기 전 동안 유저의 키 입력에 따른 블록 이동
                        if (playTimerEnd)
                        {
                            ++timeCnt;
                            UpdateDisplay();
                            Thread T = new Thread(PlayTimer);
                            playTimerEnd = false;
                            T.Start();
                        }
                        if (!Console.KeyAvailable)
                        {
                            continue;
                        }
                        ConsoleKeyInfo cki = Console.ReadKey(true);
                        string         s   = cki.Key.ToString();

                        if (s == "P")                           // 일시 정지
                        {
                            msg.ShowMessage("일시정지", false);
                            while (true)
                            {
                                ConsoleKeyInfo cki2 = Console.ReadKey(true);
                                string         s2   = cki2.Key.ToString();
                                if (s2 == "P")
                                {
                                    msg.ShowMessage("일시정지", true);
                                    msg.StartCount();
                                    break;
                                }
                            }
                        }
                        else if (s == "Q")                           // 메뉴로 돌아가기
                        {
                            return;
                        }
                        else if (s == "C")                           // 홀드
                        {
                            if (!canHold)
                            {
                                continue;
                            }
                            canHold = false; curHeld = true;
                            f.Put(hBlock, true);
                            tmp      = new Block(hBlock.type);
                            hBlock   = new Block(cur.type);
                            hBlock.x = STX - 2 * BSIZE - 2;
                            hBlock.y = STY;
                            f.Put(hBlock, false);

                            if (!holdUsed)
                            {
                                holdUsed = true;
                                wantNext = true;
                            }
                            else
                            {
                                wantNext = false;
                            }
                            break;
                        }
                        else if (s.Contains("Arrow") || s == "Spacebar" || s == "Z" || s == "X")
                        {
                            int prev = cur.y;
                            recentMove = f.BlockMove(ref cur, s);
                            recentS    = s;
                            // Lock Delay중 움직였을 때 떨어질 곳이 생기는 경우
                            if (isLockDelay && !LockDelay(cur))
                            {
                                break;
                            }
                            // Lock Delay가 아닌 도중 움직인 직후에 Lock Delay가 걸려야 하는 경우
                            if (!isLockDelay && LockDelay(cur))
                            {
                                isLockDelay = true; break;
                            }
                            // Lock Delay중 다음 키를 눌렀을 때는 바로 블록이 놓여지게 함
                            if (s == "Spacebar")
                            {
                                break;
                            }
                        }
                    }
                    nextTimer = nextTimer % MAX + 1;
                    if (!curHeld)
                    {
                        // lockTimer 또는 dropTimer가 다 됨
                        if (recentS != "Spacebar" && isLockDelay && recentMove)
                        {
                            continue;                             // Lock Delay 시간 초기화
                        }
                        int prev = cur.y;
                        f.BlockMove(ref cur, "DownArrow");
                        if (cur.y == prev)
                        {
                            wantNext = true;
                            canHold  = true;
                            break;
                        }
                    }
                    else                       // 기존에 있던 cur을 필드 state상에서 지우기
                    {
                        f.Put(cur, true);
                        f.Put(f.GetTrans(cur), true);
                        break;
                    }
                }
                // 현재 블록에 대한 처리 완료
                // 다음 스폰될 블록이 홀드 블록이라면 게임오버 또는 업데이트 진행x
                if (curHeld)
                {
                    curHeld = false; continue;
                }
                // 게임오버 검사
                gameOver = false;
                if (f.mode == "어려움" && trashTimerEnd)
                {
                    if (r.Next(0, 9876) % 13 <= 5)
                    {
                        hole = r.Next(0, W);
                    }
                    bool res = UpdateDisplay(true, hole);
                    if (!res)
                    {
                        gameOver = true; break;
                    }                                                       // 게임 오버
                    trashTimerEnd = false;
                    Thread B = new Thread(TrashTimer);
                    B.Start();
                }
                else
                {
                    UpdateDisplay(false, -1);
                    for (int i = 0; i < W; ++i)
                    {
                        if (f.state[i, EXTRA - 1] > 0)
                        {
                            gameOver = true;
                        }
                    }
                    if (gameOver)
                    {
                        break;
                    }
                }
                // 게임 클리어 검사 (그림없애기 모드만 해당)
                if (f.mode != "그림없애기")
                {
                    continue;
                }
                gameClear = true;
                for (int i = 0; i < W; ++i)
                {
                    for (int j = 0; j < L + EXTRA; ++j)
                    {
                        if (f.state[i, j] == (int)ConsoleColor.Gray)
                        {
                            gameClear = false;
                        }
                    }
                }
                if (gameClear)
                {
                    break;
                }
            }
            // 게임이 terminate 되었음
            if (f.mode == "그림없애기" && gameClear)               // 게임 클리어 안내
            {
                msg.ShowMessage("게임클리어", false);
                Thread.Sleep(1000);
                msg.ShowMessage("▶ 게임클리어(Spacebar/Enter로 진행)", false);
                MyFunction.WaitForExit();
                RecordManager rm = new RecordManager(GAMENAME);
                rm.UpdateRecord(f.mapName, "시간", timeCnt, true);
            }
            else               // 게임 오버 안내
            {
                msg.ShowMessage("게임오버", false);
                Thread.Sleep(1000);
                msg.ShowMessage("▶ 게임오버(Spacebar/Enter로 진행)", false);
                MyFunction.WaitForExit();
                if (f.mode == "그림없애기")
                {
                    return;
                }
                RecordManager rm = new RecordManager(GAMENAME);
                rm.UpdateRecord(f.mode, "점수", (int)f.score, false);
            }
        }
コード例 #2
0
 void Awake()
 {
     instance = this;
 }