당신은 주제를 찾고 있습니까 “오목 게임 만들기 – 오목게임 프로그래밍“? 다음 카테고리의 웹사이트 https://you.aodaithanhmai.com.vn 에서 귀하의 모든 질문에 답변해 드립니다: https://you.aodaithanhmai.com.vn/blog/. 바로 아래에서 답을 찾을 수 있습니다. 작성자 일상코딩 이(가) 작성한 기사에는 조회수 16,051회 및 좋아요 147개 개의 좋아요가 있습니다.
Table of Contents
오목 게임 만들기 주제에 대한 동영상 보기
여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!
d여기에서 오목게임 프로그래밍 – 오목 게임 만들기 주제에 대한 세부정보를 참조하세요
오목을 두는 게임을 직접 프로그래밍 해보자!
영상 이미지 소스 : 픽사베이(pixabay)
음성 소스 : typecast.ai
Outro: CE Designs
#알파오 #오목 #프로그래밍
오목 게임 만들기 주제에 대한 자세한 내용은 여기를 참조하세요.
Javascript 오목 게임 만들기 – Enjoy Life~~
Javascript 오목 게임 만들기 … (오목 이후 제작한 게임) … HTML,CSS는 별거 없고, 게임승리 이미지를 안보이게 넣어뒀다가 오목이 만들어졌을 때 …
Source: mrkool.tistory.com
Date Published: 9/14/2021
View: 4458
[최종본] C++를 활용한 오목게임 만들기 – AI모드의 OOP적 설계
다행이도 오목에 관련된 알고리즘이 설명되어있는 블로그를 찾았다. 이 블로그를 참고하여 OOP적으로 설계된 AI모드의 오목게임을 만들어보았다.
Source: apape1225.tistory.com
Date Published: 11/26/2021
View: 5166
17 프로젝트: 오목 게임 만들기 | CloudStudying
자바 프로그래밍의 꽃, 조립식 프로그래밍! 17 프로젝트: 오목 게임 만들기. 오목 게임 만들기.
Source: cloudstudying.kr
Date Published: 8/17/2021
View: 533
※ 게임 만들기 (오목 게임)
게임 만들기 (오목 게임). – 참고: 비주얼 C++ MFC 쉽게 따라하기, 세진북스 MFC 연구회, 세진북스, 2011. – 규칙 1: 메뉴에 저장 및 불러오기 기능 추가.
Source: www.mokwon.ac.kr
Date Published: 1/1/2022
View: 8346
[c언어 오목] 세상 간단한 오목 만들기 – 컴공과컴맹효묘의블로그
이 글에서 나오는 오목은 최대한 단순화시켜서 오목의 필수적인 요소들만 가져와서 간단하게 오목을 둘 수 있는 게임을 만들어봤습니다. 헤더파일.
Source: hyomyo.tistory.com
Date Published: 12/23/2022
View: 91
[파이썬 간단한 게임 만들기] 9. 오목 아니고 4목 – ai-creator
[파이썬 간단한 게임 만들기] 9. 오목 아니고 4목 … 오목과 비슷한 형태로 진행되며, 2명의 플레이어가 번갈아 가며 자신의 돌을 놓습니다.Source: ai-creator.tistory.com
Date Published: 1/17/2021
View: 7523
[Python – Pygame] 오목(Omok) – 1단계 – 네이버 블로그
1단계 목표는 바둑판에 오목을 두어볼 수 있는 GUI 환경과 승패를 판정할 수 … 파이게임으로 오목을 만들기 위한 첫 단계로 룰이 적용이 안되었고, …
Source: m.blog.naver.com
Date Published: 6/2/2021
View: 2085
주제와 관련된 이미지 오목 게임 만들기
주제와 관련된 더 많은 사진을 참조하십시오 오목게임 프로그래밍. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

주제에 대한 기사 평가 오목 게임 만들기
- Author: 일상코딩
- Views: 조회수 16,051회
- Likes: 좋아요 147개
- Date Published: 2019. 8. 24.
- Video Url link: https://www.youtube.com/watch?v=XWJRRDTV62o
Javascript 오목 게임 만들기
슈퍼범생
오목 게임. 아이들이랑 놀 겸해서 만들어봤다.
완성본은 아래에서…
omog-geim.bryanko555.repl.co
(오목 이후 제작한 게임)
HTML,CSS는 별거 없고, 게임승리 이미지를 안보이게 넣어뒀다가 오목이 만들어졌을 때 나타나게 했다.
큰 틀에서, 바둑판의 돌이 놓여지는 눈금 하나하나가 배열로 되어있고, 돌이 없는 곳은 -1, 검은 돌이 놓여지면 1, 하얀 돌이 놓여지면 2로 배열이 구성되는 식이다.
원래 아래처럼 보이는 배열인데, 콘솔창에 위 그림처럼 보이도록 해야 x,y좌표를 찾기 쉬워진다.
아래와 같이 콘솔창에 눈금열만큼 줄바꿈을 넣어서 실제 바둑판처럼 숫자가 나열되어 보여주게 해준다.
오목에서 고려해야 할 요소들이다.
] 돌의 위치 x,y를 배열의 위치로 바꿔주고, 반대로 배열의 위치를 x,y좌표로 바꿔주는 함수가 필요하다.
19칸 실제 바둑판에서, x=3,y=1는 배열의 22번째 위치이고, 배열의 5번째 위치는 x=4,y=0이다. (첫 줄은 0)
] 마우스 클릭한 위치를 파악해서 돌을 그리는데, 대충 찍어도 정확한 눈금에 돌이 그려지도록 보정한다.
] 그 자리에 이미 돌이 놓여져 있으면(그 위치의 숫자가 -1이 아니면) 그림이 안그려지게 하고,
비어져 있으면 차례에 따라서 흑이나 백 돌을 그린다.
] 무르기 기능. 돌을 놓을 때마다 그 차례의 바둑판 배열 전체를 또 다른 배열(여기서는 lastBoard[ ])에 넣어나가다가, 무르기가 실행되면 바로 직전의 바둑판 배열을 불러와서 그대로 바둑판을 그려준다.
] 이제 가장 중요한 승패 판정. 돌이 놓여질때 그 돌의 가로,세로,대각선 여덟 방향으로 돌의 색깔들을 파악해서 다섯 개가 놓여졌는지를 보면 되는데, 그냥하면 마지막 돌이 양쪽 끝에 놓여졌을 때만 인지하기 때문에,
돌이 오목의 중간에 놓여지면서 오목이 완성되는 경우도 파악할 수 있도록 고려해야 한다.
재미로 ‘무르기’와 ‘다시하기’에 우리 아들 목소리를 녹음해서 활용했다.
음악 재생은 읽어서 변수에 할당하고, 재생함수 실행.
let audio1 = new Audio(‘tik.mp3’);
let audio2 = new Audio(‘beep.wav’);
audio1.play();
audio2.play();
전체 코드는 아래 링크에서…
repl.it/@BryanKo555/omog-geim
승패확인 함수에서 돌이 오목의 중간에 놓여졌을 때도 5개인지를 확인할 수 있도록 하는 것에서 나름 고민을 했고, 이런 고민의 과정과 그 해결 됬을 때의 기쁨이 코딩하는 즐거움이라고 생각한다.
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받을 수 있습니다.
[최종본] C++를 활용한 오목게임 만들기 – AI모드의 OOP적 설계
반응형
1. 개요
드디어 AI(?)모드를 환성하였다. 말이 AI모드지 사실상 1인 플레이 모드이다. 아주 간단한 판별 알고리즘을 사용하였다. 다행이도 오목에 관련된 알고리즘이 설명되어있는 블로그를 찾았다. 이 블로그를 참고하여 OOP적으로 설계된 AI모드의 오목게임을 만들어보았다. 다음은 내가 참고한 블로그 글의 주소이다.
참고자료: https://ku-hug.tistory.com/2
기존에 만들어둔 Concave클래스를 상속받았기에 AI모드 역할을 하는 ConcaveAI의 기능은 몇 되지 않는다. 가중치를 설정하고 그 가중치에 따라 착수를 하는 코드가 대표적이다. 따라서 이 코드를 이해하려면 Concave Class를 꼭 본 후, ConcaveAI Class를 봐주길 바란다. 다음은 Concave Class에 대해 설명된 블로그 글이다.
Concave Class: apape1225.tistory.com/55
2. 설계방법
“방법을 알면 그것을 그대로 코드로 옮길 수 있어야 한다.” 내가 프로그래밍을 공부할 때 생각하는 나만의 방향성이다. 이 목표를 이루기 위해선 보다 많은 기능을 알고 보다 다양한 사고를 알아야 할 것이다. 내가 이번에 배운 STL과 같은 것이 해당된다고 생각하며 나름 뿌듯한 느낌으로 코드를 작성했다.
ConacaveAI와 ConcavePvP의 가장 큰 차이점은 AI모드에서는 사용자가 자신이 흑돌인지, 백돌인지를 선택할 수 있어야 한다는 것이다. 이를 구현하기 위해 state라는 변수를 만들어 AI가 자신의 돌인지 사용자의 돌인지를 판단하여 가중치를 설정할 수 있게 구성하였다.
가중치 설정방법은 의외로 간단하였다. 물론 위에 블로그의 방법을 사용하여 그런 것일 수도 있다. 그러나 Concave클래스에서 승패를 판별하는 메소드인 checkWin()메소드를 조금 변형하였더니, 손쉽게 해결되었다. checkWin()은 5개의 연속된 돌을 찾는 메소드라면 나는 이를 약간만 변형하여 3개의 연속된 돌을 찾으면 되기 때문이다. 다음은 소스코드이다.
3. 소스코드
일단 ConcaveAI 클래스를 보면서 구성을 설명해보겠다.
– ConcaveAI.h
#pragma once #include “Concave.h” #include “InfoWindow.h” #include
class ConcaveAI : Concave, InfoWindow { private: array , SIZE> weight; bool player; bool turn = true; const char *black; const char *white; bool state; void moveDir(); void setWeight(); void setAI(); void setX(int x) { posX = x; } void setY(int y) { posY = y; } void printWeight(); public: ConcaveAI(); ~ConcaveAI(); void playConcave(); }; playConcave()메소드는 말그대로 게임이 실행되는 메소드이다. printWeight()는 가중치를 출력하는 메소드이다. 그렇다. 나는 아이다라는 아주 훌륭한 디버깅툴이 있어도 저런 방식으로 디버깅을 진행한다…… 다음은 간단한 메소드들의 설명이다.
moveDir() : 사용자로부터 키를 입력받아 화면에서 커서의 위치를 이동하는 메소드
setWeight() : 가중치를 설정하는 메소드
setAI() : 가중치를 바탕으로 AI가 착수할 위치를 판별하는 메소드
setX(), setY() : setAI()메소드에서 사용하기 위해 작성하였다. 원하는 위치로 posX와 posY의 값을 설정하게 한다. (posX와 posY는 Concave의 변수이다.)
다음은 메소드들의 코드이다.
– ConcaveAI.cpp
#include “ConcaveAI.h” ConcaveAI::ConcaveAI() { for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) weight[i][j] = 0; } printInfo(); printBord(); printfMessage("흑돌은 0, 백돌은 1를 눌러주세요!",getX(),getY()); int buff; buff = getch(); if (buff == '1') { player = false; black = "AI의 차례입니다."; white = "player의 차례입니다."; } else { player = true; black = "player의 차례입니다."; white = "AI의 차례입니다."; } } ConcaveAI::~ConcaveAI() { } void ConcaveAI::moveDir() { while (true) { int dir; dir = getch(); switch (dir) { case 'w': moveX(-1); break; case 's': moveX(1); break; case 'a': moveY(-1); break; case 'd': moveY(1); break; case 'h': return; default: printfMessage("올바른 키를 입력해주세요!", getY() * 2, getX()); } gotoXY(getY() * 2, getX()); } } void ConcaveAI::setWeight() { int buff; if (getColor()) weight[getX()][getY()] = 255; else weight[getX()][getY()] = 256; if (state) { buff = -1; } else { buff = 1; } if (checkRange(getX()-1, getY()-1) && weight[getX() - 1][getY() - 1] < 255) weight[getX()-1][getY()-1] += buff; if (checkRange(getX() - 1, getY()) && weight[getX() - 1][getY()] < 255) weight[getX() - 1][getY()] += buff; if (checkRange(getX() - 1, getY() + 1) && weight[getX() - 1][getY() + 1] < 255) weight[getX() - 1][getY() + 1] += buff; if (checkRange(getX(), getY() - 1) && weight[getX()][getY() - 1] < 255) weight[getX()][getY() - 1] += buff; if (checkRange(getX(), getY() + 1) && weight[getX()][getY() + 1] < 255) weight[getX()][getY() + 1] += buff; if (checkRange(getX() + 1, getY() - 1) && weight[getX() + 1][getY() - 1] < 255) weight[getX() + 1][getY() - 1] += buff; if (checkRange(getX() + 1, getY()) && weight[getX() + 1][getY()] < 255) weight[getX() + 1][getY()] += buff; if (checkRange(getX() + 1, getY() + 1) && weight[getX() + 1][getY() + 1] < 255) weight[getX() + 1][getY() + 1] += buff; for (int i = 0; i < SIZE; i++) { //3개 연속의 돌을 검사하는 코드 for (int j = 0; j < SIZE; j++) { if (weight[i][j] > 254) { int buff = weight[i][j]; int countStone = 1; if (checkRange(i + 1, j) && weight[i + 1][j] == buff && checkRange(i + 2, j) && weight[i + 2][j] == buff) { if (checkRange(i – 1, j) && weight[i – 1][j] < 255) weight[i - 1][j] += state ? -30 : 30; if (checkRange(i + 3, j) && weight[i + 3][j] < 255) weight[i + 3][j] += state ? -30 : 30; } if (checkRange(i, j + 1) && weight[i][j + 1] == buff && checkRange(i, j + 2) && weight[i][j + 2] == buff) { if (checkRange(i, j - 1) && weight[i][j - 1] < 255) weight[i][j - 1] += state ? -30 : 30; if (checkRange(i, j + 3) && weight[i][j + 3] < 255) weight[i][j + 3] += state ? -30 : 30; } if (checkRange(i + 1, j + 1) && weight[i + 1][j + 1] == buff && checkRange(i + 2, j + 2) && weight[i + 2][j + 2] == buff) { if (checkRange(i - 1, j - 1) && weight[i - 1][j - 1] < 255) weight[i - 1][j - 1] += state ? -30 : 30; if (checkRange(i + 3, j + 3) && weight[i + 3][j + 3] < 255) weight[i + 3][j + 3] += state ? -30 : 30; } if (checkRange(i + 1, j - 1) && weight[i + 1][j - 1] == buff && checkRange(i + 2, j - 2) && weight[i + 2][j - 2] == buff) { if (checkRange( i - 1, j + 1) && weight[i - 1][j + 1] < 255) weight[i - 1][j + 1] += state ? -30 : 30; if (checkRange(i + 3, j - 3) && weight[i + 3][j - 3] < 255) weight[i + 3][j - 3] += state ? -30 : 30; } } } } } void ConcaveAI::setAI() { int buffX = 0, buffY = 0; int min = weight[buffX][buffY]; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { if (weight[i][j] < min) { buffX = i; buffY = j; min = weight[i][j]; } } } setX(buffX); setY(buffY); gotoXY(getY() * 2, getX()); } void ConcaveAI::playConcave() { gotoXY(0, 0); while (true) { if (getColor()) { printfMessage(black, getX(), getY()); state = getColor() == player; if (state) { moveDir(); } else { setAI(); } } else { printfMessage(white, getX(), getY()); state = getColor() == player; if (state) { moveDir(); } else { setAI(); } } if (getColor()) printf("○"); else printf("●"); changeBord(getX(), getY(), getColor()); if (checkWin()) { if (getColor()) printfMessage("흑돌이 승리하였습니다.", getY() * 2, getX()); else printfMessage("백돌이 승리하였습니다.", getY() * 2, getX()); return; } setWeight(); reverseColor(); } } void ConcaveAI::printWeight() { gotoXY(40, 40); for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { printf("%4d ", weight[i][j]); } printf(" "); } } 3. 결어 OOP적인 설계를 경험하려면 이정도의 프로그램은 작성해야한다고 생각했으며 설계 과정에서 개인적인 즐거움이 느껴졌기에 여기까지 완성한 것 같다. 그러나 아직도 "OOP적인 설계를 하였다!" 라는 만족감은 얻지 못하였다. 내가 사용한 것은 결국 '상속'밖에 없기 때문이다. 연산자 재정의, 오버로드, 가상함수와 같은 훌륭한 OOP적 기능을 사용하지 못했다. 내가 작성한 것은 말만 AI이지 사실은 1인모드이다. 그것도 초급 난이도라고 할 수 있다. 진정한 오목 AI는 트리 자료구조를 사용해 최소최대 알고리즘, 가지치기 알고리즘을 구현하여 만들 수 있다. 하지만 나는 절대적인 값을 설정하는 방법도 아직 이해하지 못하였다. 트리라는 자료구조는 학교의 '자료구조' 강의와 혼자 알고리즘을 독학하며 만난 이진탐색트르 같은 것들이지 최소최대, 가지치기와 같은 고급알고리즘은 공부하지 못했다. 프로젝트를 진행하면서 나의 한계를 많이 느꼈다. 그래도 방학이라는 긴 기간동한 나름 할 일이 생겨 기쁘기도 하다. 최소최대알고리즘, 가지치기알고리즘을 공부하여 이 블로그에 제대로된 AI 오목을 올렸으면 좋겠다. 반응형
17 프로젝트: 오목 게임 만들기
17 프로젝트: 오목 게임 만들기
# 오목 게임 만들기
## 기본 코드 Omok.java “` public class Omok { public static void main(String[] args) { Player user = new Player(“사용자”, “O”); Player computer = new Player(“컴퓨터”, “X”); Board board = new Board(19); play(board, user, computer); } private static void play(Board board, Player user, Player computer) { board.print(); } } “` Board.java “` public class Board { int size; String[][] map; Board(int size) { this.size = size; map = new String[size][size]; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { map[row][col] = "."; } } } public void print() { for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { System.out.print(" " + map[row][col]); } System.out.println(); } } } ``` Player.java ``` public class Player { String name; String stone; Player(String name, String stone) { this.name = name; this.stone = stone; } } ``` ## 실행결과 ``` . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ``` ## Step 1: 좌표 출력하기 좌측에 0, 1, 2, 3, ... , 18 하단에 A, B, C, ... , S 의 좌표 표시를 하시오. ## Step 2: 바둑판에 돌 놓기 "J 9"를 입력하면 해당 좌표에 "O" 돌을 표시하시오. ## Step 3: 검은 돌, 흰 돌 번갈아 가며 놓기 사용자 A와 B가 번갈아가며 O, X, O, X, ... 의 돌을 놓도록 하시오. ## Step 4: "오목"이 되면 게임이 종료되도록 하시오.
[c언어 오목] 세상 간단한 오목 만들기
효묘
저번에 gotoxy함수를 설명한 포스팅과 c언어로 할만한 프로젝트를 작성했었습니다. 그 예시를 직접 포스팅하면 좋을 것 같아서 포스팅해봅니다.
개인적으로 가장 만만하다고 생각하는 것은 오목입니다. 물론 33규칙 알고리즘을 적용하면 복잡해지지만, 33규칙을 빼고 구현하면 굉장히 쉽습니다. 이 글에서 나오는 오목은 최대한 단순화시켜서 오목의 필수적인 요소들만 가져와서 간단하게 오목을 둘 수 있는 게임을 만들어봤습니다.
헤더파일
stdio.h // 기본 입출력
// 기본 입출력 windows.h // 좌표 설정
// 좌표 설정 conio.h // 입력
// 입력 string.h // 입력 문자열 처리
전처리
MAX_N 19 // 바둑(오목)판의 크기
// 바둑(오목)판의 크기 DRAW_BLACK printf(“○”) // 검은 돌 출력 (cmd에서는 색반전이기 때문)
// 검은 돌 출력 (cmd에서는 색반전이기 때문) DRAW_WHITE printf(“●”) // 하얀 돌 출력
// 하얀 돌 출력 BLACK 1 // 검은 돌 정의
// 검은 돌 정의 WHITE 2 // 하얀 돌 정의
drawInit()함수
초기 19×19 오목판을 만들어주는 함수입니다.
void drawInit() { gotoxy(0, 0); for (int i = 0; i < MAX_N; i++) { for (int j = 0; j < MAX_N; j++) { gotoxy(j, i); if (i == 0) { if (j == 0) printf("┌"); else if (j == MAX_N - 1) printf("┐"); else printf("┬"); } else if (j == 0) { if (i == MAX_N - 1) printf("└"); else printf("├"); } else if (j == MAX_N - 1) { if (i == MAX_N - 1) printf("┘"); else printf("┤"); } else if (i == MAX_N - 1) { printf("┴"); } else printf("┼"); } printf(" "); } for (int i = 0; i < MAX_N; i++) { gotoxy(MAX_N, i); printf("%d", i + 1); gotoxy(i, MAX_N); printf("%c", i + 'A'); } gotoInput(); printf("fin."); } drawStone(int y, int x, int stone)함수 stone의 값에 따라 주어진 좌표에 돌을 둡니다. 돌을 둘 수 없는 상황이거나 stone이 흑, 백이 아닌 잘못된 값이면 0을 리턴, 성공적으로 돌을 두면 1을 리턴한다. int drawStone(int y, int x, int stone) { // stone이 1이면 흑, 2면 백 if (board[y][x] || x<0 || x>=MAX_N || y<0 || y>=MAX_N) return 0; gotoxy(x, y); if (stone == BLACK) { DRAW_BLACK; board[y][x] = BLACK; } else if (stone == WHITE) { DRAW_WHITE; board[y][x] = WHITE; } else return 0; return 1; }
inputCode(int *x, int*y) 함수
좌표를 문자열로 받고 좌표를 넘겨주는 함수. 잘못된 문자열(좌표)가 입력되면 x와 y는 -1로 준다.
void inputCode(int* y, int* x) { gotoInput(); printf(“Input Coordinate (A19): “); char s[10]; gets_s(s, sizeof(s)); *x = s[0] – ‘A’; if (strlen(s) > 3) return ; if (strlen(s) == 3) *y = (s[1] – ‘0’) * 10 + s[2] – ‘0’ – 1; else if (strlen(s) == 2) *y = s[1] – ‘0’ – 1; else *y = *x = -1; gotoInput(); printf(“Input Coordinate (A19): \t\t\t”); return; }
checkFinish(int t) 함수
매개변수가 좌표인데, x와 y로 받는게 아니라 t로 받는다. t를 x와 y로 변환시켜 계산한다.
0,0 부터 MAX_N, MAX_N 미만까지 모든 좌표를 이동하며 게임이 끝났는지 확인한다.
게임이 끝났으면,(5개의 돌이 연속으로 한 줄) 해당 color를 리턴한다. 아니면 0을 리턴.
int checkFinish(int t) { if (t == MAX_N * MAX_N) return 0; int x = t % MAX_N; int y = t / MAX_N; int color = board[y][x]; int dir[3] = { 0 }; for (int i = 0; i < 5 && color != 0; i++) { if (x + i < MAX_N && color == board[y][x + i]) dir[0]++; if (y + i < MAX_N && color == board[y + i][x]) dir[1]++; if (x + i < MAX_N && y + i < MAX_N && color == board[y + i][x + i]) dir[2]++; } for (int i = 0; i < 3; i++) if (dir[i] == 5) return color; return checkFinish(t + 1); } gotoInput() 함수 입력받을 좌표로 이동한다. void gotoInput() { gotoxy(21, 20); } gotoxy()함수 이전 글 참고. 전체 코드
[파이썬 간단한 게임 만들기] 9. 오목 아니고 4목
ai-creator
유치한 게임에 오신 것을 환영합니다.
이번에는 4목 게임을 만들어 보겠습니다.
아래와 같은 순서로 배워보겠습니다.
1. 목표
2. 사전 준비
3. 소스 코드 (전체)
4. 사전 지식
5. 구현 순서
6. 정리
1. 목표
이번 장에서는 4목 게임을 만들어 보도록 하겠습니다.
이번에 만들 게임은 4목 게임입니다. 4목 게임의 규칙은 다음과 같습니다.
오목과 비슷한 형태로 진행되며, 2명의 플레이어가 번갈아 가며 자신의 돌을 놓습니다. 하지만 오목과 달리 2차원의 공간에 돌을 놓는 형태가 아니라 3차원 형태로 공이 중력의 영향을 받아 각 행에 하나씩 차곡차곡 쌓이게 되는 형태입니다. 따라서 열별로 자신의 돌을 잘 놓아 상대방의 연속 배치를 막으며, 자신의 돌이 4개가 연속되게 놓는 것이 목표입니다.
[그림 9-1] 사목 게임이번 장에서는 이 4목 게임을 구현 해보도록 하겠습니다.
2. 사전 준비
– 게임판 구상
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import pygame # 1. pygame 선언 pygame.init() # 2. pygame 초기화 # 3. pygame에 사용되는 전역변수 선언 BLUE = ( 0 , 0 , 255 ) BLACK = ( 0 , 0 , 0 ) RED = ( 255 , 0 , 0 ) YELLOW = ( 255 , 255 , 0 ) large_font = pygame.font.SysFont( None , 72 ) CELL_SIZE = 100 COLUMN_COUNT = 7 ROW_COUNT = 6 P1_WIN = 1 P2_WIN = 2 DRAW = 3 SCREEN_WIDTH = 700 SCREEN_HEIGHT = 700 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) grid = np.zeros((ROW_COUNT, COLUMN_COUNT)) mouse_x, mouse_y = pygame.mouse.get_pos() clock = pygame.time.Clock() # 4. pygame 무한루프 def runGame(): global done while not done: clock.tick( 10 ) screen.fill(WHITE) runGame() pygame.quit() Colored by Color Scripter cs
게임을 진행할 화면을 다음과 같이 설정하도록 하겠습니다.
7~10번 라인 : 게임에 사용되는 색상 RGB 값
11번 라인(게임 폰트) : 게임 내부에서 게임 결과를 표시할 폰트 설정
12번 라인 : 각 셀의 크기
13~14번 라인 : 4목 게임판의 가로열과 세로행의 갯수
15~17번 라인 : 게임 종료 플래그
18~19번 라인 : 게임판의 크기(700X700)
22번 라인 : numpy의 zeros() 함수를 이용하여 6X7의 2차원 배열을 생성(전부 0으로 초기화)
23번 라인 : 마우스로 돌을 놓을 위치를 잡기 위한 초기 위치 지정
3. 소스 코드 (전체)
파일명 : connectFour.py
drive.google.com/drive/folders/1P7-ibtlJKUEet1lbqkSAg7N8RyxOza_o?usp=sharing
4. 사전 지식
1) 4목의 게임승리 조건
4목의 승리조건은 같은 색의 돌이 연속하여 4개가 위치하게 되는 것입니다. 따라서 게임의 승리조건에 대하여 수직, 수평, 대각선(/, \) 방향의 모든 연속된 돌을 검증하는 것이 필요합니다.
따라서 각 게임루프마다 매번 승리 조건을 탐색해야 합니다. 이 승리조건에 대한 검증을 함수를 통해 구현해보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def is_winner(grid, piece): for column_index in range (COLUMN_COUNT – 3 ): for row_index in range (ROW_COUNT): if grid[row_index][column_index] = = piece and grid[row_index][column_index + 1 ] = = piece and grid[row_index][column_index + 2 ] = = piece and grid[row_index][column_index + 3 ] = = piece: return True for column_index in range (COLUMN_COUNT): for row_index in range (ROW_COUNT – 3 ): if grid[row_index][column_index] = = piece and grid[row_index + 1 ][column_index] = = piece and grid[row_index + 2 ][column_index] = = piece and grid[row_index + 3 ][column_index] = = piece: return True for column_index in range (COLUMN_COUNT – 3 ): for row_index in range (ROW_COUNT – 3 ): if grid[row_index][column_index] = = piece and grid[row_index + 1 ][column_index + 1 ] = = piece and grid[row_index + 2 ][column_index + 2 ] = = piece and grid[row_index + 3 ][column_index + 3 ] = = piece: return True for column_index in range (COLUMN_COUNT – 3 ): for row_index in range ( 3 , ROW_COUNT): if grid[row_index][column_index] = = piece and grid[row_index – 1 ][column_index + 1 ] = = piece and grid[row_index – 2 ][column_index + 2 ] = = piece and grid[row_index – 3 ][column_index + 3 ] = = piece: return True Colored by Color Scripter cs
먼저 공통적인 코드 구성부터 살펴보도록 하겠습니다.
각 4개의 For문이 크게 존재하며 각가 수직, 수평, 대각선(/ , \)의 연속 검증을 하는 코드입니다.
column_index와 row_index를 활용해 모든 셀을 돌아가며 검증을 하게 됩니다. 하지만, 각각의 셀을 모두 찾는 것이 아니라 구조적으로 출발점이 될 수 있는 위치에서만 검증을 하도록 하고 있습니다.
예를 들어 수평 검증을 한다고 하면 총 7개의 열 중 좌측의 4개의 열만 가로로 연속하는지 검증하면 됩니다.
[그림 9-2] 4목의 승리 조건다음으로 for문 안에있는 검증하는 코드는 다음과 같습니다.
먼저 인자로 들어온 piece는 각 돌의 색깔을 의미하며, 시작점 부터 각 인덱스에 1씩 추가해 4개의 모든 돌이 일치하는지 AND를 활용하여 조건문을 돌게 됩니다. 이때 하나라도 일치하지 않는다면 혹은 돌이 존재하지 않는 다면 조건에 부합하지 않게 됩니다.
1~5번 라인 : 수평 검증(-)
7~10번 라인 : 수직 검증(ㅣ)
12~15번 라인 : 대각선 검증(/)
17~20번 라인 : 대각선 검증(\)
5. 구현 순서
구현 순서는 다음과 같습니다.
Step1 마우스 이벤트 처리(돌 놓기) Step2 화면 그리기
Step1) 마우스 이벤트 처리(돌 놓기)
먼저 돌을 놓기 전 해당 돌을 놓을 수 있는지에 대한 검증을 하는 함수부터 선언하도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def is_free_column_index(grid, column_index): if column_index < 0 or column_index > COLUMN_COUNT – 1 : return False return grid[ROW_COUNT – 1 ][column_index] = = 0 def get_free_row_index(grid, column_index): for row_index in range (ROW_COUNT): if grid[row_index][column_index] = = 0 : return row_index def is_grid_full(count): if count = = 42 : return True return False Colored by Color Scripter cs
is_free_column_index : column_index를 활용하여 해당 열에 돌이 들어갈 수 있는지를 판별합니다. 만약 열의 크기인 7을 초과하여 돌을 놓게 된다면 해당 돌은 놓을 수 없도록 False를 리턴해줍니다.
get_free_row_index : 해당하는 좌표에 돌이 없는지 판별하는 함수 입니다. 이후 마우스 이벤트 처리 부분에서 만약 빨간 돌이 놓이게 되면 해당 위치의 값은 1, 노란 돌이 놓이게 되면 해당 위치의 값을 2로 변경해주기 때문에 해당 값이 0이면 비어있다고 판단하여 돌을 놓을 수 있게 row_index를 아래부터 검증하여 리턴합니다.(최하단 부터 차곡차곡)
is_grid_full : 돌을 놓을 때마다 count를 추가하여 이 count가 42값이 되게 되면 draw 플래그로 변경하도록 True, False를 리턴합니다.
다음은 게임루프에서 처리입니다.
이번에는 게임 진행을 마우스를 이용하여 조금 특이한 방식으로 진행해보도록 하겠습니다.
이전 장에서 학습한 것 처럼 pygame에서 event가 발생했을 때, event.pos()를 통해 마우스의 해당 좌표를 구할 수 있었습니다. 이번에는 마우스의 x좌표만을 이용하여 게임을 진행합니다.
이유는 앞서 설명한 것 처럼 오목과 같이 x, y축을 기준으로 빈공간에 돌을 아무데나 넣을 수 있는 것이 아니라, y축에 돌이 차곡차곡 쌓이는 구조이기 때문에 x축만 사용하여 돌을 놓을 수 있는 공간을 좌우로만 설정하도록 하겠습니다.
[그림 9-3] 돌의 가동범위1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 def runGame(): game_over = 0 turn = 0 count = 0 while True : clock.tick( 30 ) screen.fill(BLACK) for event in pygame.event.get(): if event.type = = pygame.QUIT: break elif event.type = = pygame.MOUSEBUTTONDOWN: column_index = event.pos[ 0 ] / / CELL_SIZE count + = 1 if turn = = 0 : if is_free_column_index(grid, column_index): row_index = get_free_row_index(grid, column_index) grid[row_index][column_index] = 1 if is_winner(grid, 1 ): game_over = P1_WIN elif is_grid_full(count): game_over = DRAW turn + = 1 turn % = 2 elif turn = = 1 : if is_free_column_index(grid, column_index): row_index = get_free_row_index(grid, column_index) grid[row_index][column_index] = 2 if is_winner(grid, 2 ): game_over = P2_WIN elif is_grid_full(count): game_over = DRAW turn + = 1 turn % = 2 Colored by Color Scripter cs
먼저 게임 종료 플래그로 사용할 변수와 무승부를 검증하기 위한 count 변수 마지막으로 빨간돌, 노란돌의 turn을 체크할 변수를 선언해주도록 합니다.
13~15번 라인은 돌을 놓을 좌표를 정하는 부분입니다. 먼저 마우스 클릭이벤트가 발생하게 되면 event.pos()를 이용하여 x좌표만을 가져오며 count 값을 증가시켜주도록 합니다.
17~28번 라인은 빨간돌의 차례를 진행하는 부분입니다. turn 변수를 활용하여 0, 1값을 번갈아가며 사용하도록 하기에 0일 때는 빨간돌 1일때는 노란돌의 차례를 진행하도록 합니다. 먼저 앞서 선언한 is_free_column_index() 함수를 이용하여 검증을 한 뒤, get_free_row_index()함수를 호출하여 row_index값을 가져옵니다.
이후 grid의 해당 좌표 값에 앞서 설명한 것 처럼 해당하는 돌의 값(빨 : 1, 노 : 2)으로 변경하도록 합니다.
다음으로 앞서 선언한 is_winner() 함수를 이용하여 해당 grid에서 발생하는 모든 승리조건에 대한 검증을 진행한 뒤, 만약 승리가 아니라면 is_full_grid() 함수를 통해 무승부를 체크합니다.
마지막으로 turn을 변경하도록 합니다.
30~41번 라인은 노란돌의 차례를 진행하는 부분입니다. 앞의 빨간돌의 차례와 동일하게 진행되며 grid의 해당 위치 값을 2로 바꿔주는 부분에만 차이가 있습니다.
Step2) 화면 그리기
이번에는 앞의 코드를 기반으로 게임판을 출력해보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 width = 700 pygame.draw.rect(screen, BLACK, pygame.Rect( 0 , 0 , width, CELL_SIZE)) if turn = = 0 : pygame.draw.circle(screen, RED, (mouse_x, CELL_SIZE / / 2 ), CELL_SIZE / / 2 – 5 ) else : pygame.draw.circle(screen, YELLOW, (mouse_x, CELL_SIZE / / 2 ), CELL_SIZE / / 2 – 5 for column_index in range (COLUMN_COUNT): for row_index in range (ROW_COUNT): pygame.draw.rect(screen, BLUE, pygame.Rect(column_index * CELL_SIZE, row_index * CELL_SIZE + CELL_SIZE, CELL_SIZE, CELL_SIZE)) pygame.draw.circle(screen, BLACK, (column_index * CELL_SIZE + CELL_SIZE / / 2 , row_index * CELL_SIZE + CELL_SIZE + CELL_SIZE / / 2 ), CELL_SIZE / / 2 – 5 for column_index in range (COLUMN_COUNT): for row_index in range (ROW_COUNT): if grid[row_index][column_index] = = 1 : height = CELL_SIZE * (ROW_COUNT + 1 ) pygame.draw.circle(screen, RED, (column_index * CELL_SIZE + CELL_SIZE / / 2 , height – (row_index * CELL_SIZE + CELL_SIZE / / 2 )), CELL_SIZE / / 2 – 5 ) elif grid[row_index][column_index] = = 2 : height = CELL_SIZE * (ROW_COUNT + 1 ) pygame.draw.circle(screen, YELLOW, (column_index * CELL_SIZE + CELL_SIZE / / 2 , height – (row_index * CELL_SIZE + CELL_SIZE / / 2 )), CELL_SIZE / / 2 – 5 ) if game_over > 0 : if game_over = = P1_WIN: p1_win_image = large_font.render( ‘Red (1) Win’ , True , RED) screen.blit(p1_win_image, p1_win_image.get_rect(centerx = SCREEN_WIDTH / / 2 , centery = SCREEN_HEIGHT / / 2 )) elif game_over = = P2_WIN: p2_win_image = large_font.render( ‘Yellow (2) Win’ , True , RED) screen.blit(p2_win_image, p2_win_image.get_rect(centerx = SCREEN_WIDTH / / 2 , centery = SCREEN_HEIGHT / / 2 )) else : draw_image = large_font.render( ‘Draw’ , True , RED) screen.blit(draw_image, draw_image.get_rect(centerx = SCREEN_WIDTH / / 2 , centery = SCREEN_HEIGHT / / 2 )) pygame.display.update() Colored by Color Scripter cs
1,2번 라인은 돌을 놓기 전 마우스를 기반으로 미리 위치를 볼 수 있도록 게임타일 위에 직사각형의 검은색 타일을 출력하는 코드입니다.
3~6번 라인은 위에서 생성한 타일 위에 각 턴에 맞추어 색깔별로 미리 보는 돌을 출력하는 라인입니다. 해당 돌은 circle() 함수를 이용해서 출력되며 이 돌은 게임판에 놓이는 것이 아닌 놓이기 전 미리보는 용도로 마우스 클릭이벤트 전에는 이동만 하는 용도입니다.
8~11번 라인은 게임판을 생성하는 코드입니다.
먼저 각 셀을 돌면서 정사각형의 파란색 도형을 그려줍니다. 이 정사각형의 크기는 셀의 사이즈를 기반으로 위치 인덱스(row, column) 에 맞추어 생성하도록 합니다.
다음으로는 앞서 그린 파란색 정사각형 도형과 곂쳐 circle()을 이용한 원을 그려주어, 마치 해당 칸안에 동그란 원이 비어있는 것처럼 만들어 주도록합니다.
13~20번 라인은 앞서 마우스 이벤트 처리를 통해 처리한 좌표값을 기반으로 1일 때는 빨간색 원을, 2일 때는 노란색 원을 그려주는데, 원도 동일하게 모든 셀을 돌며 각각의 색깔 도형을 그려줍니다.
22~31번 라인은 게임 종료플래그를 기반으로 종료 결과를 화면에 출력하는 부분입니다.
초기에 선언한 large_font를 기반으로 메세지를 작성하며, blit() 함수를 이용해 화면 정중앙에 메세지를 그려줍니다.
각각 red 승리, yellow 승리, 무승부를 출력합니다.
[그림 9-4] 게임 종료6. 정리
이번 장에서는 앞서 배운 pygame의 기본 구조와 게임 루프, 이벤트 처리를 기반으로 4목 게임을 구현 해봤습니다.
먼저, 게임승리 조건에 대한 처리를 기반으로 게임을 진행할 수 있도록 사전학습을 한 뒤 진행을 했으며,
Step 1) 마우스 이벤트 처리(돌 놓기) > 마우스 좌클릭을 기반으로 각 위치에 대한 조건 처리 후 게임 진행
Step 2) 화면 그리기 -> 사각형과 원을 곂쳐 그려 새로운 도형그리기 및 마우스 미리보기 출력
을 배웠습니다.
이번 게임 생성을 기반으로 조금 더 쉬운 오목 게임을 직접 구현해보는 것은 어떨까요?^^
ㅁ 참고
토닥토닥 파이썬
도움이 되셨다면, 좋아요 / 구독 버튼 눌러주세요~
저작물의 저작권은 작성자에게 있습니다.
공유는 자유롭게 하시되 댓글 남겨주세요~
상업적 용도로는 무단 사용을 금지합니다.
끝까지 읽어주셔서 감사합니다^^
[Python – Pygame] 오목(Omok) – 1단계
돌을 그리야 하는 상황은 착수를 할 때와 undo, redo를 할 때입니다.
착수할 때나 redo로 다시 그려줄 땐 하나씩만 그려 넣으면 되고, undo를 위해서는 칸마다의 이미지가 없을 경우 보드부터 다시 그려줘야 합니다. 위에서 언급했듯이 undo를 위해서 다시 그려서 넣으려니 느려지는 경향이 있어서 이미지를 떴는데, 이때 바둑알을 놓고 빈 곳의 이미지도 떠놨지만 모서리 변 점이 있는 좌표 등 분리하려면 너무나 귀찮아서 보드 이미지만 사용하고, 바둑돌은 다시 그려 넣는 방법으로 해보니 속도 저하를 느낄 수 없어서 undo를 할 때는 다시 그려 넣었고, 위 함수가 사용되었습니다.
착수와 redo 할 때도 따로 구분해서 각기 돌을 그려 넣은 기능을 넣었었는데, 이 포스트를 작성하려다 보니 기능이 겹치고, 전부를 다시 그려도 속도 저하가 없는 점을 고려해서 함수를 분리하고, 단순화했습니다.
돌을 그리기 위해서는 좌표와 돌의 컬러가 필요하고, 착수와 redo 할 때는 돌의 개수가 증가하지만 undo를 할 때는 돌의 개수가 감소하므로 별도의 변수 increase를 둬서 이곳에서 처리하도록 했습니다.
돌이 놓이면 보드에도 표시를 해줘야 되므로 보드에서 사용될 좌표를 얻어와서 보드에 저장합니다.
다음으로 이미지를 그려주고(slef.hide_numbers) 번호 표시상태라면 번호를 넣어줍니다.
돌을 그려 넣었으니 self.id도 같이 연동해서 변화를 주고, 돌을 바꿔줍니다.
돌의 컬러가 검은색은 1, 흰색은 2이므로
3 – 현재의 돌을 해주면 2일 경우 1이 되고, 1일 때 2가 됩니다. 그러므로 이 식 self.turn = 3 – self.turn은 돌을 교환해주는 역할을 합니다.
다음은 undo() 함수입니다.
키워드에 대한 정보 오목 게임 만들기
다음은 Bing에서 오목 게임 만들기 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.
이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!
사람들이 주제에 대해 자주 검색하는 키워드 오목게임 프로그래밍
- 알파고
- 딥러닝
- AI
- 머신러닝
- 기계학습
- machine learning
- Artificial intelligence
- Deep learning
- 확률과통계
- 컴퓨터
- 프로그래밍
- 컴퓨터과학
- computer science
- 컴퓨터 사이언스
- 신경망
- DNN
- 심층신경망
- Neuron
- neural network
- network
- Deep neural network
- 인공지능
- 목소리
- 가상음성
- 성우
- 알파오
- 게임프로그래밍
오목게임 #프로그래밍
YouTube에서 오목 게임 만들기 주제의 다른 동영상 보기
주제에 대한 기사를 시청해 주셔서 감사합니다 오목게임 프로그래밍 | 오목 게임 만들기, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.