3-1 스네이크
class Program
{
static void Main(string[] args)
{
// 게임 속도를 조정하기 위한 변수입니다. 숫자가 클수록 게임이 느려집니다.
int gameSpeed = 100;
int foodCount = 0; // 먹은 음식 수
// 게임을 시작할 때 벽을 그립니다.
DrawWalls();
// 뱀의 초기 위치와 방향을 설정하고, 그립니다.
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)
{
var key = Console.ReadKey(true).Key;
switch (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;
}
}
// 뱀이 음식을 먹었는지 확인합니다.
if (snake.Eat(food))
{
foodCount++; // 먹은 음식 수를 증가
food.Draw();
// 뱀이 음식을 먹었다면, 새로운 음식을 만들고 그립니다.
food = foodCreator.CreateFood();
food.Draw();
if (gameSpeed > 10) // 게임이 점점 빠르게
{
gameSpeed -= 10;
}
}
else
{
// 뱀이 음식을 먹지 않았다면, 그냥 이동합니다.
snake.Move();
}
Thread.Sleep(gameSpeed);
// 벽이나 자신의 몸에 부딪히면 게임을 끝냅니다.
if (snake.IsHitTail() || snake.IsHitWall())
{
break;
}
Console.SetCursorPosition(0, 21); // 커서 위치 설정
Console.WriteLine($"먹은 음식 수: {foodCount}"); // 먹은 음식 수 출력
}
WriteGameOver(); // 게임 오버 메시지를 출력합니다.
Console.ReadLine();
}
static void WriteGameOver()
{
int xOffset = 25;
int yOffset = 22;
Console.SetCursorPosition(xOffset, yOffset++);
WriteText("============================", xOffset, yOffset++);
WriteText(" GAME OVER", xOffset, yOffset++);
WriteText("============================", xOffset, yOffset++);
}
static void WriteText(string text, int xOffset, int yOffset)
{
Console.SetCursorPosition(xOffset, yOffset);
Console.WriteLine(text);
}
// 벽 그리는 메서드
static void DrawWalls()
{
// 상하 벽 그리기
for (int i = 0; i < 80; i++)
{
Console.SetCursorPosition(i, 0);
Console.Write("#");
Console.SetCursorPosition(i, 20);
Console.Write("#");
}
// 좌우 벽 그리기
for (int i = 0; i < 20; i++)
{
Console.SetCursorPosition(0, i);
Console.Write("#");
Console.SetCursorPosition(80, i);
Console.Write("#");
}
}
}
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
}
public class Snake
{
public List<Point> body; // 뱀의 몸통을 리스트로 표현합니다.
public Direction direction; // 뱀의 현재 방향을 저장합니다.
public Snake(Point tail, int length, Direction _direction)
{
direction = _direction;
body = new List<Point>();
for (int i = 0; i < length; i++)
{
Point p = new Point(tail.x, tail.y, '*');
body.Add(p);
tail.x += 1;
}
}
// 뱀을 그리는 메서드입니다.
public void Draw()
{
foreach (Point p in body)
{
p.Draw();
}
}
// 뱀이 음식을 먹었는지 판단하는 메서드입니다.
public bool Eat(Point food)
{
Point head = GetNextPoint();
if (head.IsHit(food))
{
food.sym = head.sym;
body.Add(food);
return true;
}
else
{
return false;
}
}
// 뱀이 이동하는 메서드입니다.
public void Move()
{
Point tail = body.First();
body.Remove(tail);
Point head = GetNextPoint();
body.Add(head);
tail.Clear();
head.Draw();
}
// 다음에 이동할 위치를 반환하는 메서드입니다.
public Point GetNextPoint()
{
Point head = body.Last();
Point nextPoint = new Point(head.x, head.y, head.sym);
switch (direction)
{
case Direction.LEFT:
nextPoint.x -= 2;
break;
case Direction.RIGHT:
nextPoint.x += 2;
break;
case Direction.UP:
nextPoint.y -= 1;
break;
case Direction.DOWN:
nextPoint.y += 1;
break;
}
return nextPoint;
}
// 뱀이 자신의 몸에 부딪혔는지 확인하는 메서드입니다.
public bool IsHitTail()
{
var head = body.Last();
for (int i = 0; i < body.Count - 2; i++)
{
if (head.IsHit(body[i]))
return true;
}
return false;
}
// 뱀이 벽에 부딪혔는지 확인하는 메서드입니다.
public bool IsHitWall()
{
var head = body.Last();
if (head.x <= 0 || head.x >= 80 || head.y <= 0 || head.y >= 20)
return true;
return false;
}
}
public class FoodCreator
{
int mapWidth;
int mapHeight;
char sym;
Random random = new Random();
public FoodCreator(int mapWidth, int mapHeight, char sym)
{
this.mapWidth = mapWidth;
this.mapHeight = mapHeight;
this.sym = sym;
}
// 무작위 위치에 음식을 생성하는 메서드입니다.
public Point CreateFood()
{
int x = random.Next(2, mapWidth - 2);
// x 좌표를 2단위로 맞추기 위해 짝수로 만듭니다.
x = x % 2 == 1 ? x : x + 1;
int y = random.Next(2, mapHeight - 2);
return new Point(x, y, sym);
}
}
3-2 블랙잭 만들기
using System;
using System.Collections.Generic;
public enum Suit { Hearts, Diamonds, Clubs, Spades }
public enum Rank { Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace }
// 카드 한 장을 표현하는 클래스
public class Card
{
// 카드의 무늬를 나타냄
public Suit Suit { get; private set; }
// 카드의 숫자를 나타냄
public Rank Rank { get; private set; }
public Card(Suit s, Rank r)
{
Suit = s;
Rank = r;
}
// 카드의 블랙잭에서의 점수를 반환하는 메소드
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
{
// 덱에 있는 카드들
private List<Card> cards;
public Deck()
{
cards = new List<Card>();
// 모든 무늬와 숫자의 조합에 대해 카드를 생성
foreach (Suit s in Enum.GetValues(typeof(Suit)))
{
foreach (Rank r in Enum.GetValues(typeof(Rank)))
{
cards.Add(new Card(s, r));
}
}
// 카드를 섞는다
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];
cards.RemoveAt(0);
return card;
}
}
// 플레이어의 패를 표현하는 클래스
public class Hand
{
// 패에 있는 카드들
private List<Card> cards;
public Hand()
{
cards = new List<Card>();
}
// 카드를 패에 추가하는 메소드
public void AddCard(Card card)
{
cards.Add(card);
}
// 패의 총점을 계산하는 메소드
public int GetTotalValue()
{
int total = 0;
int aceCount = 0;
foreach (Card card in cards)
{
if (card.Rank == Rank.Ace)
{
aceCount++;
}
total += card.GetValue();
}
// 에이스가 있고 총점이 21점을 넘을 때, 에이스를 1점으로 취급
while (total > 21 && aceCount > 0)
{
total -= 10;
aceCount--;
}
return total;
}
}
// 플레이어를 표현하는 클래스
public class Player
{
// 플레이어의 패
public Hand Hand { get; private set; }
public Player()
{
Hand = new Hand();
}
// 카드를 뽑는 메소드
public Card DrawCardFromDeck(Deck deck)
{
Card drawnCard = deck.DrawCard();
Hand.AddCard(drawnCard);
return drawnCard;
}
}
// 딜러를 표현하는 클래스
public class Dealer : Player
{
// 딜러는 총점이 17점 미만일 때 계속해서 카드를 뽑는다
public void KeepDrawingCards(Deck deck)
{
while (Hand.GetTotalValue() < 17)
{
Card drawnCard = DrawCardFromDeck(deck);
Console.WriteLine($"딜러는 '{drawnCard}'을(를) 뽑았습니다. 현재 총합은 {Hand.GetTotalValue()}점입니다.");
}
}
}
// 블랙잭 게임을 표현하는 클래스
public class Blackjack
{
private Player player;
private Dealer dealer;
private Deck deck;
public void PlayGame()
{
deck = new Deck();
player = new Player();
dealer = new Dealer();
// 게임 시작, 플레이어와 딜러는 각각 두 장의 카드를 뽑는다
for (int i = 0; i < 2; i++)
{
player.DrawCardFromDeck(deck);
dealer.DrawCardFromDeck(deck);
}
Console.WriteLine("게임을 시작합니다!");
Console.WriteLine($"플레이어의 초기 카드 합: {player.Hand.GetTotalValue()}");
Console.WriteLine($"딜러의 초기 카드 합: {dealer.Hand.GetTotalValue()}");
// 플레이어의 차례, 21점이 넘지 않는다면 계속해서 카드를 뽑을 수 있다
while (player.Hand.GetTotalValue() < 21)
{
Console.Write("카드를 더 뽑으시겠습니까? (y/n): ");
string input = Console.ReadLine();
if (input.ToLower() == "y")
{
Card drawnCard = player.DrawCardFromDeck(deck);
Console.WriteLine($"'{drawnCard}'을(를) 뽑았습니다. 현재 총합은 {player.Hand.GetTotalValue()}점입니다.");
}
else
{
break;
}
}
// 딜러의 차례, 총합이 17점이 넘을 때까지 계속해서 카드를 뽑는다
Console.WriteLine("딜러의 차례입니다.");
dealer.KeepDrawingCards(deck);
Console.WriteLine($"딜러의 총합은 {dealer.Hand.GetTotalValue()}점입니다.");
// 승자 판정
if (player.Hand.GetTotalValue() > 21)
{
Console.WriteLine("플레이어의 카드 합이 21점을 초과했습니다. 딜러의 승리입니다.");
}
else if (dealer.Hand.GetTotalValue() > 21)
{
Console.WriteLine("딜러의 카드 합이 21점을 초과했습니다. 플레이어의 승리입니다.");
}
else if (player.Hand.GetTotalValue() > dealer.Hand.GetTotalValue())
{
Console.WriteLine("플레이어의 카드 합이 더 높습니다. 플레이어의 승리입니다.");
}
else
{
Console.WriteLine("딜러의 카드 합이 더 높거나 같습니다. 딜러의 승리입니다.");
}
}
}
class Program
{
static void Main(string[] args)
{
Blackjack game = new Blackjack();
game.PlayGame();
}
}