C# 문법 - 3주차 과제

이준호·2023년 11월 9일
0

챕터3: 과제

📌 스네이크 게임

namespace SnakeGame
{
    using System;
    using System.Collections.Generic;
    using System.Threading;

    class Program
    {
    #region Main
        static void Main(string[] args)
        {
            ConsoleKeyInfo keys;    // 방향키 입력값

            WallDraw(); // 벽 그리기

            // 뱀의 초기 위치와 방향을 설정하고, 그립니다.
            Point p = new Point(4, 5, '*');
            Snake snake = new Snake(p, 4, Direction.RIGHT);
            snake.Draw();

            // 음식의 위치를 무작위로 생성하고, 그립니다.
            FoodCreator foodCreator = new FoodCreator(80, 20, '$');
            Point food = foodCreator.CreateFood();
            food.Draw();

            // 게임 루프: 이 루프는 게임이 끝날 때까지 계속 실행됩니다.
            while (true)
            {
                // 키 입력이 있는 경우에만 방향을 변경합니다.
                if (Console.KeyAvailable)
                {
                    keys = Console.ReadKey(true);
                    switch(keys.Key)
                    {
                        case ConsoleKey.UpArrow:
                            snake.direction = Direction.UP;
                            break;
                        case ConsoleKey.DownArrow:
                            snake.direction = Direction.DOWN;
                            break;
                        case ConsoleKey.LeftArrow:
                            snake.direction = Direction.LEFT;
                            break;
                        case ConsoleKey.RightArrow:
                            snake.direction = Direction.RIGHT;
                            break;
                        default:
                            break;

                    }
                }
                // 뱀 이동
                snake.Move();

                // 벽이랑 충돌시 (게임이 종료)
                if (snake.CrashWall() || snake.CrashBody()) break;
               

                // 음식을 먹음
                Point snakeHead = snake.body[0];
                if(food.IsHit(snakeHead)) // 뱀 머리가 음식과 충돌했다면
                {
                    snake.EatFood();    // 뱀 꼬리 추가

                    food = foodCreator.CreateFood();    // 음식 좌표 랜덤 섞기
                    food.Draw();    // 음식 생성
                }

                // 뱀 그려줌
                snake.Draw();

                Thread.Sleep(100); // 게임 속도 조절 (이 값을 변경하면 게임의 속도가 바뀝니다)

                Console.SetCursorPosition(0, 22);
                Console.Write($"현재 몸의 길이 : {snake.body.Count}   먹은 음식의 수 : {snake.foodCount}");

                // 뱀의 상태를 출력합니다 (예: 현재 길이, 먹은 음식의 수 등)
            }
        }
        static void WallDraw()
        {
            for(int x = 0; x < 80; x++)
            {
                Console.SetCursorPosition(x, 0);
                Console.Write('#');
                Console.SetCursorPosition(x, 20);
                Console.Write('#');
            }
            for(int y = 0; y < 21; y++)
            {
                Console.SetCursorPosition(0, y);
                Console.Write('#');
                Console.SetCursorPosition(80, y);
                Console.Write('#');
            }
        }
    }
#endregion

    #region Snake
    // 뱀의 상태와 이동, 음식 먹기, 자신의 몸에 부딪혔는지 확인 등의 기능
    public class Snake
    {      
        public Direction direction { get; set; }   // 뱀의 방향

        public List<Point> body;   // 뱀 몸 

        public int foodCount {  get; set; }     // 음식 먹은 수

        // Snake 생성자
        public Snake(Point head, int size, Direction direction)
        {
            this.direction = direction;
            this.body = new List<Point>();
            body.Add(head);
            for (int i = 0; i < size-1; i++)
            {
                Point p = new Point(head.x, head.y, head.sym);
                body.Add(p);    // p : 4, 5, '*'
            }
        }

        public void Draw()
        {
            foreach(Point p in body)
            {
                p.Draw();
            }
        }

        public void Move()
        {
            Point head = body[0];
            int x = head.x, y = head.y;
            switch(direction)
            {
                case Direction.RIGHT:
                    x += 1; 
                    break;
                case Direction.LEFT:
                    x -= 1;            
                    break;
                case Direction.UP:
                     y -= 1;
                    break;
                case Direction.DOWN:
                    y += 1;
                    break;
                default:
                    break;
            }
            body.Insert(0, new Point(x, y, head.sym));
            body[^1].Clear();
            body.RemoveAt(body.Count - 1);
        }

        public void EatFood()
        {
            Point tail = body[^1];  // tail에 body[마지막인덱스]에 들어있는 값(x,y,sym)들을 넣는다. 데이터형은 Point
            Point realTail = new Point(tail.x, tail.y, tail.sym);    // 새로운 생성자를 realTail에 넣어준다
            body.Add(realTail); // body list에 추가
            foodCount++;
        }

        // 벽에 충돌
        public bool CrashWall()
        {
            if (body[0].x <= 0 || body[0].x >= 80 || body[0].y <= 0 || body[0].y >= 20) return true;
            else return false;
        }

        // 몸이랑 충돌
        public bool CrashBody()
        {
            for(int i = 1; i < body.Count; i++)
            {
                if (body[0].IsHit(body[i])) return true;
            }

            return false;
        }
    }
    #endregion

    #region FoodCretor
    // 맵의 크기 내에서 무작위 위치에 음식을 생성
    public class FoodCreator
    {
        public int width { get; set; }  // 가로
        public int height { get; set; }  // 세로
        public char sym { get; set; }   // 밥

        Random food = new Random(); // 랜덤 밥 찍기

        // 생성자
        public FoodCreator(int width, int height, char sym)
        {
            this.width = width;
            this.height = height;
            this.sym = sym;
        }

        // 음식을 랜덤 좌표에 지정
        public Point CreateFood()
        {
            int x = food.Next(1, width - 1);    // 맵의 가로 길이의 랜덤 x좌표
            int y = food.Next(1, height - 1);   // 맵의 세로 길이의 랜덤 y좌표

            return new Point(x,y,sym);
        }
    }
    #endregion

    #region Point
    public class Point
    {
        public int x { get; set; }
        public int y { get; set; }
        public char sym { get; set; }

        // Point 클래스 생성자
        public Point(int _x, int _y, char _sym)
        {
            x = _x;
            y = _y;
            sym = _sym;
        }

        // 점을 그리는 메서드
        public void Draw()
        {
            Console.SetCursorPosition(x, y);
            Console.Write(sym);
        }

        // 점을 지우는 메서드
        public void Clear()
        {
            sym = ' ';
            Draw();
        }

        // 두 점이 같은지 비교하는 메서드
        public bool IsHit(Point p)
        {
            return p.x == x && p.y == y;
        }
    }
    // 방향을 표현하는 열거형입니다.
    public enum Direction
    {
        LEFT,
        RIGHT,
        UP,
        DOWN
    }
    #endregion
}






📌 블랙잭 게임

namespace BlackJack
{
    public enum Suit { Hearts, Diamonds, Clubs, Spades }
    public enum Rank { Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}
    internal class Program
    {
        static void Main(string[] args)
        {
            BlackJack blackJack = new BlackJack();
            blackJack.StartGame();
        }
    }

    // 블랙잭 게임 구현
    public class BlackJack
    {
        public Deck deck { get; set; }
        public Player player { get; set; }  
        public Dealer dealer { get; set; }  
        public Card card { get; set; }  

        // Player와 Dealer에게 초기 카드 2장씩 주는 함수
        public void StartCard()
        {
            deck = new Deck();
            player = new Player();
            dealer = new Dealer();

            for (int i = 0; i < 2; i++)
            {
                player.DrawCardFromDeck(deck);  // 플레이어에게 카드 한장 분배
                dealer.DrawCardFromDeck(deck);  // 딜러에게 카드 한장 분배
                Console.Write($"{player.playerCard} ");
            }
        }

        public void StartGame()
        {
            int choice = 0;

            Console.WriteLine("BlackJack게임을 시작합니다.\n");
            Console.WriteLine("카드를 섞습니다...... \n");
            Console.Write("플레이어의 카드 : ");
            StartCard();
            Console.WriteLine();
            Console.WriteLine($"플레이어의 점수 : {player.Score()}점");
            Console.WriteLine($"딜러의 점수 : {dealer.Score()}점\n");

            while(true)
            {
                Console.Write("카드 한장 뽑는다. -> 1 승부를 한다. ->  2 \n");
                Console.Write("입렵 해주십시오. : ");
                choice = int.Parse(Console.ReadLine());

                // 1. 카드를 한장 뽑는다.
                if (choice == 1)
                {
                    player.DrawCardFromDeck(deck);
                    dealer.DrawCardFromDeck(deck);
                    Console.WriteLine();
                    Console.WriteLine($"플레이어가 뽑은 카드 : {player.playerCard}");
                    Console.WriteLine($"플레이어의 점수 : {player.Score()}점");

                    // 딜러가 17점보다 커지면 승부
                    if (dealer.Score() > 17)
                    {
                        Console.WriteLine("딜러가 승부를 걸었습니다!\n");
                        if (Math.Abs(21 - player.Score()) < Math.Abs(21 - dealer.Score()))
                        {
                            Console.WriteLine($"플레이어의 점수 : {player.Score()}");
                            Console.WriteLine($"딜러의 점수 : {dealer.Score()}");
                            Console.WriteLine("플레이어가 이겼습니다!");
                            break;
                        }
                        else
                        {
                            Console.WriteLine($"플레이어의 점수 : {player.Score()}");
                            Console.WriteLine($"딜러의 점수 : {dealer.Score()}");
                            Console.WriteLine("딜러가 이겼습니다...");
                            break;
                        }
                    }

                }
                // 2. 승부를 한다.
                else if (choice == 2)
                {
                    // Player와 Dealer의 점수를 비교.
                    if (Math.Abs(21 - player.Score()) < Math.Abs(21 - dealer.Score()))
                    {
                        Console.WriteLine($"플레이어의 점수 : {player.Score()}");
                        Console.WriteLine($"딜러의 점수 : {dealer.Score()}");
                        Console.WriteLine("플레이어가 이겼습니다!");
                        break;
                    }
                    else
                    {
                        Console.WriteLine($"플레이어의 점수 : {player.Score()}");
                        Console.WriteLine($"딜러의 점수 : {dealer.Score()}");
                        Console.WriteLine("딜러가 이겼습니다...");
                        break;
                    }
                }
                else
                {
                    Console.WriteLine("잘못된 입력.");
                    Console.ReadLine();
                }
            }
            Console.WriteLine();
        }

        // Player가 카드를 뽑으면 Dealer도 카드를 뽑는다.

        // 승부를 하면 Player와 Dealer의 보유한 카드의 점수를 비교 21점에 가까운쪽이 승리
    }

    // 카드 한장을 표현하는 클래스
    public class Card
    {
        public Suit suit { get; private set; }
        public Rank rank { get; private set; }

        // Card 생성자 
        public Card (Suit suit, Rank rank)
        {
            this.suit = suit;
            this.rank = rank;
        }

        // 카드의 값에 맞는 숫자 반환
       public int GetValue()
        {
            if ((int)rank <= 10)
            {
                return (int)rank;
            }
            else if ((int)rank <= 13)
            {
                return 10;
            }
            else
            {
                return 11;
            }
        }

        // 카드 정보 표시
        public override string ToString()
        {
            return $"{rank} of {suit}";
        }

    }

    // 덱을 표현하는 클래스
    public class Deck
    {
        List<Card> cards;

        // 덱 생성자
        public Deck()
        {
            cards = new List<Card>();   // 52장의 카드를 가지는 List

            // 카드 생성
            foreach (Suit suit in Enum.GetValues(typeof(Suit)))
            {
                foreach (Rank rank in Enum.GetValues(typeof(Rank)))
                {
                    Card card = new Card(suit, rank);   // 새로운 카드를 찍고
                    cards.Add(card);    // cards에 카드를 추가해준다.
                }
            }
            Shuffle();  // 카드 섞기
        }

        // 카드 섞기
        public void Shuffle()
        {
            Random rand = new Random();

            for (int i = 0; i < cards.Count; i++)
            {
                int j = rand.Next(i, cards.Count);
                Card temp = cards[i];
                cards[i] = cards[j];
                cards[j] = temp;
            }
        }

        // 카드를 뽑는다.
       public Card DrawCard()
        {
            Card card = cards[0];   // card에 cards[0]의 정보를 담는다.
            cards.RemoveAt(0);  // cards[0]을 List에서 제거한다.
            return card;    // card에 담긴 정보를 return
        }
    }

    // 패를 표현하는 클래스
    public class Hand
    {
        private List<Card> cards;

        // Hand 생성자
        public Hand() 
        {
            cards = new List<Card>();
        }

        // 카드 한장 추가
        public void AddCard(Card card)
        {
            cards.Add(card);
        }

        // 총 점수 확인
        public int GetTotalValue()
        {
            int total = 0;
            int aceCount = 0;

            // cards 리스트를 순회
            foreach (Card card in cards)
            {
                if (card.rank == Rank.Ace)
                {
                    aceCount++; // Ace가 있으면 Count++
                }
                total += card.GetValue();   // 쥐고있는 카드의 점수 합산
            }

            // 21점 이상인데 Ace를 가지고있다?
            while (total > 21 && aceCount > 0)
            {
                total -= 10;    // Ace점수를 10점 빼준다. ( Ace는 1 or 11점 )
                aceCount--;
            }

            return total;
        }
    }

    // 플레이어를 표현하는 클래스
    public class Player
    {
        public Hand hand { get; private set; }

        public string playerCard = " ";

        public int score = 0;

        // Player 생성자
        public Player()
        {
            hand = new Hand();
        }

        // 카드를 뽑는다.
        public Card DrawCardFromDeck(Deck deck)
        {
            Card drawnCard = deck.DrawCard();
            hand.AddCard(drawnCard);
            // Console.Write($"{drawnCard.ToString()}   ");
            playerCard = drawnCard.ToString();
            score += drawnCard.GetValue();
            return drawnCard;
        }

        public int Score()
        {
            score = hand.GetTotalValue();
            return score;
        }
    }

    // 딜러를 표현하는 클래스
    public class Dealer
    {
       public Hand hand { get; private set; }

        public int score = 0;

       public Dealer()
        {
            hand = new Hand();
        }

        public Card DrawCardFromDeck(Deck deck)
        {
            Card drawnCard = deck.DrawCard();
            hand.AddCard(drawnCard);
            return drawnCard;
        }
        public int Score()
        {
            score = hand.GetTotalValue();
            return score;
        }
    }
}
profile
No Easy Day

0개의 댓글