본문 바로가기

프로그래밍

[C# & GDI+] 그리기 예제 : 보드게임 SET 그리기 부분 코드

사용자 삽입 이미지

http://gun0123.tistory.com/109

SET 게임에 대한 설명은 위에 설명되어 있다. 아래 코드는 GDI+ 함수들을 이용하여 그리기부분만을 구현한 코드이다.

간략히 설명하자면, Card 클래스에는 카드의 총 4가지 특징을 가지고 있는데 각각의 특징마다 3가지의 속성을 가지고 있다.

이 Card클래스로 81장의 카드 객체를 만들고 섞은다음 앞의 배열 맨 처음부터 12번째까지의 카드를 Form에 그려주기 위해 다음과 같이 코드를 작성하였다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using CardLibrary;
using System.Drawing.Drawing2D;
namespace SETProject
{
    public partial class Form1 : Form
    {      
        private Rectangle[] rect;
        private int cardW = 120, cardH = 150;
        private ArrayList selCard;
        private ArrayList deck;
        public Form1()
        {
            InitializeComponent();
            rect = new Rectangle [12];
            selCard = new ArrayList();
            deck = new ArrayList();
           
            //81개의 카드를 deck에 생성
            foreach (CardShapeCategory aShape in Enum.GetValues(typeof(CardShapeCategory)))
            {
                foreach (CardColorCategory aColor in Enum.GetValues(typeof(CardColorCategory)))
                {
                    foreach (CardNumberCategory aNumber in Enum.GetValues(typeof(CardNumberCategory)))
                    {
                        foreach (CardFillCategory aFill in Enum.GetValues(typeof(CardFillCategory)))
                        {
                            deck.Add(new Card(aShape, aColor, aNumber, aFill));
                        }
                    }
                }
            }
            //deck을 섞음
            shuffleDeck();
        }
        private void shuffleDeck()
        {
            Random randomGenerator = new Random();
            int count = deck.Count;
            for (int i = count - 1; i >= 1; --i)
            {
                // Pick an random number 0 through i inclusive.
                int j = randomGenerator.Next(i + 1);
                // Swap array[i] and array[j]
                Card temp = (Card)deck[i];
                deck[i] = deck[j];
                deck[j] = temp;
            }
            /*for (int i = 0; i < deck.Count; i++)
            {
                Card card = (Card)deck[i];
                Console.WriteLine("Property Value: {0}, {1}, {2}, {3}", card.ShapeProperty, card.ColorProperty, card.NumberProperty, card.FillProperty);
            }*/
        }
        private void Form1_Load(object sender, EventArgs e)
        {
           
        }
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
        }
        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            Graphics g = this.CreateGraphics();
          
            /*for(int i=0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                {
                    Point p = new Point(i, j);
                    if (rect[i, j].Contains(e.X, e.Y))
                    {
                        if (selCard.Contains(p))
                        {
                            selCard.Remove(p);
                            g.DrawRectangle(Pens.Black, rect[i, j]);
                            return;
                        }
                        g.DrawRectangle(Pens.Pink, rect[i, j]);
                        selCard.Add(p);
                    }
                }*/
        }
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
           
            int x = 250, y = 100;
            for (int i = 0; i < 12; i++)
            {
                if (deck[i] == null)
                    MessageBox.Show("These are last cards", "Name Entry Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                Card card = (Card)deck[i];
                rect[i] = new Rectangle(x, y, cardW, cardH);
                Pen color = new Pen(Color.Black);
                Brush fill;
                GraphicsPath graphPath = new GraphicsPath();
                int innerX = 0, innerY = 0;
               
                int count = 0;
                //갯수 속성 지정 (ㅠㅠ 이런 노가다를)
                if (card.NumberProperty == CardNumberCategory.One)
                {
                    count = 1;
                    innerX = x + (cardW * 1 / 3);
                    innerY = y + (cardH * 1 / 3);
                }
                else if (card.NumberProperty == CardNumberCategory.Two)
                {
                    count = 2;
                    innerX = x + (cardW * 1 / 6);
                    innerY = y + (cardH * 1 / 3);
                }
                else if (card.NumberProperty == CardNumberCategory.Three)
                {
                    count = 3;
                    innerX = x + (cardW * 1 / 9);
                    innerY = y + (cardH * 1 / 3);
                }
               
                //갯수 속성 만큼 그려줌
                for (int j = 0; j < count; j++)
                {
                    //색깔 속성 지정
                    switch (card.ColorProperty)
                    {
                        case (CardColorCategory.Blue):
                            color.Color = Color.Blue;
                            break;
                        case (CardColorCategory.Green):
                            color.Color = Color.Green;
                            break;
                        case (CardColorCategory.Red):
                            color.Color = Color.Red;
                            break;
                        default:
                            Console.Write("색깔 지정 못했음.");
                            color.Color = Color.Black;
                            break;
                    }
                    //모양 속성 지정
                    switch (card.ShapeProperty)
                    {
                        case (CardShapeCategory.Ellipse):
                            graphPath.AddEllipse(innerX, innerY, 30, 50);
                            break;
                        case (CardShapeCategory.Rectangle):
                            Rectangle r = new Rectangle(innerX, innerY, 30, 50);
                            graphPath.AddRectangle(r);
                            break;
                        case (CardShapeCategory.Trapezoid):
                            Point[] p ={
                                    new Point(innerX, innerY+20),
                                    new Point(innerX+15, innerY),
                                    new Point(innerX+30, innerY+20),
                                    new Point(innerX+20, innerY+50),
                                    new Point(innerX+10, innerY+50)
                                    };
                            graphPath.AddPolygon(p);
                            break;
                    }
                    g.DrawPath(new Pen(color.Color), graphPath);
                    switch (card.FillProperty)
                    {
                        case (CardFillCategory.Full):
                            fill = new SolidBrush(color.Color);
                            e.Graphics.FillPath(fill, graphPath);
                            break;
                        case (CardFillCategory.None):
                            break;
                        case (CardFillCategory.Slash):
                            fill = new HatchBrush(HatchStyle.DottedDiamond, color.Color, Color.Empty);
                            e.Graphics.FillPath(fill, graphPath);
                            break;
                        default:
                            break;
                    }
                    innerX += 35;
                }
               
                //카드 테두리 그려주는 부분
                if ((i + 1) % 3 == 0) { x = 250; y += 170; }
                else { x += 160; }
                g.DrawRectangle(Pens.Black, rect[i]);
           
                color.Dispose();
                graphPath.Dispose();               
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < selCard.Count; i++)
            {
                Console.Write(selCard[i]);
                Console.WriteLine("\n");
            }
        }
    }
}

카드 클래스 파일은 팀원 형이 만든 클래스를 썼다. 필자는 클래스를 사용만했기 때문에 그냥 아래 파일로 첨부해 두겠다.