일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Exception
- c#
- 게임엔진
- db
- 예외처리
- cocos2d-x
- cocos2d
- Thread
- Class함수
- 입출력
- C/C++
- singleton
- 예외던지기
- Stack
- 동기화블럭
- 반복문
- java
- 프로그래밍
- oracle
- interface상속
- c++게임엔진
- c++
- 스레드
- 문자열
- unity
- 데이터베이스
- cocos2dx
- 데이터타입
- 상수변수
- Interface
- Today
- Total
초보 프로그램 개발자
cocos2D-X 로 스도쿠게임 만들기 - 기록2 본문
이전 난이도조절 버튼을 클릭하면 PlayGame Scene이 시작되며 게임이 시작된다.
해당 칸을 클릭시 색이 변하며, 숫자를 입력할수 있게 된다.
숫자는 옆의 키패드같은 모양으로 클릭해서 넣을수 있다.
Finish 버튼을 누르면 스도쿠가 성공인지 실패인지 화면에 3초 보여준뒤 사라지고,
Replay 버튼을 누르면 난이도조절로 돌아가 다시 시작할수 있다. (Finish 안해도 가능)
#include "stdafx.h"
#include "PlayGame.h"
Scene* PlayGame::createScene(int level) {
return PlayGame::create(level);
}
PlayGame* PlayGame::create(int level){
auto ret = new PlayGame();
if (ret && ret->init(level)) ret->autorelease();
else CC_SAFE_DELETE(ret);
return ret;
}
bool PlayGame::init(int level) {
if(!Scene::init()) return false;
firstRandomNumber();
copyIntToString(level);
drawLayout();
finishButton("Finish", Vec2(CENTER.x + 150, CENTER.y + 200));
replayButton("Replay", Vec2(CENTER.x + 350, CENTER.y + 200));
for (int i = 1; i <= 3; i++) {
Vec2 pos = Vec2(CENTER.x + 100 + (100 * i), CENTER.y - 50);
string num = to_string(i);
buttonCreate(num, pos);
}
for (int i = 4; i <= 6; i++) {
Vec2 pos = Vec2(CENTER.x + 100 + (100 * (i-3)), CENTER.y - 150);
string num = to_string(i);
buttonCreate(num, pos);
}
for (int i = 7; i <= 9; i++) {
Vec2 pos = Vec2(CENTER.x + 100 + (100* (i-6)), CENTER.y - 250);
string num = to_string(i);
buttonCreate(num, pos);
}
auto keybd = EventListenerKeyboard::create();
keybd->onKeyPressed = [=](EventKeyboard::KeyCode c, Event* e)->void {
};
getEventDispatcher()->addEventListenerWithSceneGraphPriority(keybd, this);
return true;
}
void PlayGame::drawLayout(){
addChild(dn = DrawNode::create());
//dn->drawRect(Vec2(50, 50), Vec2(700, 700), Color4F::GREEN);
Color4F color1 = Color4F::MAGENTA;
Color4F color2 = Color4F::WHITE;
for (int i = 0; i <= 9; i++) {
if (i % 3 == 0) {
dn->drawLine(Vec2(70 * (i + 1), 70), Vec2(70 * (i + 1), 700), color1);
dn->drawLine(Vec2(70, 70 * (i + 1)), Vec2(700, 70 * (i + 1)), color1);
}
else {
dn->drawLine(Vec2(70 * (i + 1), 70), Vec2(70 * (i + 1), 700), color2);
dn->drawLine(Vec2(70, 70 * (i + 1)), Vec2(700, 70 * (i + 1)), color2);
}
}
dn->setLineWidth(5);
int tag = 0;
for (int i = 1; i <= 9; i++) {
for (int k = 1; k <= 9; k++) {
sudokuButton(Vec2(70 * k, 70 * i), tag, 0);
tag++;
}
}
}
void PlayGame::createLevel(int level){
switch (level) {
case 1:
break;
case 2:
break;
case 3:
break;
}
}
void PlayGame::finishButton(const string& text, const Vec2& pos) {
Button* btn = Button::create(DEFAULT_UI);
btn->setAnchorPoint(Vec2(0, 0));
btn->setPosition(pos);
btn->setTitleText(text);
btn->setTitleFontSize(30.0f);
btn->setTitleColor(Color3B::BLACK);
btn->setScale9Enabled(true);
btn->setScaleX(1.5);
addChild(btn);
btn->addClickEventListener([=](Ref*)->void {
// 완료하면 스도쿠 검사 하고 성공 실패
if (checkSudoku()) {
sudokuSuccess();
}
else {
sudokuFail();
}
});
}
void PlayGame::replayButton(const string& text, const Vec2& pos) {
Button* btn = Button::create(DEFAULT_UI);
btn->setAnchorPoint(Vec2(0, 0));
btn->setPosition(pos);
btn->setTitleText(text);
btn->setTitleFontSize(30.0f);
btn->setTitleColor(Color3B::BLACK);
btn->setScale9Enabled(true);
btn->setScaleX(1.5);
addChild(btn);
btn->addClickEventListener([=](Ref*)->void {
//다시 새로운게임을 만들거나 난이도조절로 돌아가면됨
Director::getInstance()->replaceScene(Level::create());
});
}
void PlayGame::sudokuSuccess() {
DrawNode* dn = DrawNode::create();
addChild(dn);
dn->drawSolidRect(CENTER - Vec2(150, 100), CENTER + Vec2(150, 100), Color4F::WHITE);
Label* lb = Label::createWithTTF("Success!!", DEFAULT_FONT, 50.0f);
lb->setTextColor(Color4B::BLACK);
lb->setPosition(CENTER);
dn->addChild(lb);
dn->runAction(Sequence::create(DelayTime::create(3), RemoveSelf::create(true), nullptr));
}
void PlayGame::sudokuFail() {
DrawNode* dn = DrawNode::create();
addChild(dn);
dn->drawSolidRect(CENTER - Vec2(150, 100), CENTER + Vec2(150, 100), Color4F::RED);
Label* lb = Label::createWithTTF("Fail....", DEFAULT_FONT, 50.0f);
lb->setTextColor(Color4B::BLACK);
lb->setPosition(CENTER);
dn->addChild(lb);
dn->runAction(Sequence::create(DelayTime::create(3), RemoveSelf::create(true), nullptr));
}
void PlayGame::firstRandomNumber() {
srand(time(0));
for (int i = 0; i < 9; i++) {
int r = rand() % 8 + 1;
int temp = num[i];
num[i] = num[r];
num[r] = temp;
}
int index = 0;
for (int i = 0; i < 3; i++) {
for (int k = 0; k < 3; k++) {
random[i][k] = num[index];
index++;
}
}
randomNumberWidth();
randomNumberHigth(0, 0);
randomNumberHigth(0, 3);
randomNumberHigth(3, 0);
randomNumberHigth(3, 3);
randomNumberHigth(6, 0);
randomNumberHigth(6, 3);
}
void PlayGame::randomNumberWidth() {
int target = 0;
for (int i = 0; i < 3; i++) {
for (int k = 3; k < 6; k++) {
if (target == i) target++;
if (target > 2) target = 0;
random[i][k] = random[target][k - 3];
}
}
for (int i = 0; i < 3; i++) {
for (int k = 6; k < 9; k++) {
if (target == i) target++;
if (target > 2) target = 0;
random[i][k] = random[target][k - 3];
}
}
}
void PlayGame::randomNumberHigth(int x, int y) {
int target = 0;
for (int i = x; i < x + 3; i++) {
for (int k = y; k < y + 3; k++) {
if (target + x == i) target++;
if (target > 2) target = 0;
random[k + 3][i] = random[k][target+x];
}
}
}
void PlayGame::copyIntToString(int count) {
srand(time(0));
for (int i = 0; i < 9; i++) {
for (int k = 0; k < 9; k++) {
sudoku[i][k].append(to_string(random[i][k]));
}
}
#if DEBUG_SUDOKU
for (int i = 0; i < count; i++) {
int x = rand() % 9;
int y = rand() % 9;
sudoku[x][y] = ' ';
}
#endif
}
bool PlayGame::checkInt(int x, int y, int value){
for (int i = 0; i < 9; i++) {
if (random[x][i] == value && i != y) {
return false;
}
if (random[i][y] == value && i != x) {
return false;
}
}
// 3x3 부분 체크
for (int i = (x / 3) * 3; i < (x / 3) * 3 + 3; i++) {
for (int k = (y / 3) * 3; k < (y / 3) * 3 + 3; k++) {
if (i == x && k == y) {
continue;
}
else if (random[i][k] == value) {
return false;
}
}
}
return true;
}
// 스도쿠 판
void PlayGame::sudokuButton(const Vec2& pos, int tag, int level) {
Button* btn = Button::create(DEFAULT_UI);
btn->setAnchorPoint(Vec2(0, 0));
btn->setPosition(pos);
btn->setColor(Color3B(153, 204, 153));
btn->setScale(0.7);
btn->setTag(tag);
if (xIndex >= 9) {
xIndex = 0;
yIndex++;
}
btn->setTitleText(sudoku[yIndex][xIndex]);
btn->setTitleFontSize(50.0f);
btn->setTitleColor(Color3B::BLUE);
addChild(btn);
xIndex++;
// 누르면 해당 위치 퍼즐 색 변경
btn->addClickEventListener([=](Ref*)->void {
if (target == nullptr) {
target = btn;
target->setColor(Color3B(102, 153, 102));
}
else {
target->setColor(Color3B(153, 204, 153));
target = btn;
target->setColor(Color3B(102, 153, 102));
}
});
}
// 번호 누르는곳
void PlayGame::buttonCreate(const string& number, const Vec2& pos) {
Button* btn = Button::create(DEFAULT_UI);
btn->setScale9Enabled(true);
btn->setTitleText(number);
btn->setTitleColor(Color3B::BLACK);
btn->setTitleFontSize(50.0f);
btn->setPosition(pos);
addChild(btn);
// 번호를 누르면 그 번호의 Title을 해당 스도쿠퍼즐에 입력해줌
btn->addClickEventListener([=](Ref*)->void {
if (target == nullptr) return;
auto num = btn->getTitleText();
target->setTitleText(num);
target->setTitleFontSize(50.0f);
target->setTitleColor(Color3B::BLACK);
int tag = target->getTag(); // tag는 0부터 시작
sudoku[tag / 9][tag % 9] = num;
});
}
bool PlayGame::checkSudoku() {
for (int i = 0; i < 9; i++) {
for (int k = 0; k < 9; k++) {
// 체크하여 중복된다면 false
if (!check(i, k, sudoku[i][k])) {
return false;
}
}
}
// 모두 마치고 나오면 성공이니까 true
return true;
}
bool PlayGame::check(int x, int y, const string& value) {
// x축 y축 9칸 체크
for (int i = 0; i < 9; i++) {
if (sudoku[x][i] == value && i != y) {
return false;
}
if (sudoku[i][y] == value && i != x) {
return false;
}
}
// 3x3 부분 체크
for (int i = (x / 3) * 3; i < (x / 3) * 3 + 3; i++) {
for (int k = (y / 3) * 3; k < (y / 3) * 3 + 3; k++) {
if (i == x && k == y) {
continue;
}
else if (sudoku[i][k] == value) {
return false;
}
}
}
return true;
}
스도쿠 퍼즐판이랑 버튼들은 큰 어려움이 없었지만
숫자를 배치하는 부분에서 정말 큰 어려움이 생겼다. rand를 사용해서 중복되지 않게
체크해주는 함수를 이용해 스도쿠판을 만들어보려 했는데 너무 많이 연산되어서?그런지 게임이 켜지질 않았고,
1~9를 9개짜리 배열에 넣어 랜덤으로 위치를 변경하여 넣어주는것을 생각해보니 한줄 이후가 문제였다.
그래서 검색에 검색을 계속한 결과, 스도쿠퍼즐 배열에도 공식이 있다는 글을 본뒤 이거다 싶어 적용했다.
출처 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=askmrkwon&logNo=220770386091
[두뇌를 깨우는 수학퍼즐] 스도쿠 퍼즐 랜덤 생성 알고리즘(medium 버전) - 무한복제
스도쿠 퍼즐 생성 알고리즘 두 번째 포스팅입니다. 이번 포스팅은 기존에 있는 스도쿠 9x9 행렬을 무제한적...
blog.naver.com
코드를 보면 정말 난잡하고 불필요한것들이 많은데 이렇게 한번 만들어보니
이건 이렇게 저건 저렇게 하면 좋겠다는것들이 많이 보인다.
점점 더 좋아질수 있도록 더 공부해야겠다.
'cocos2dx' 카테고리의 다른 글
cocos2d-x Slider 만들기 (0) | 2022.08.06 |
---|---|
cocos2d-x Button 만들기 (0) | 2022.08.06 |
cocos2D-X 로 스도쿠게임 만들기 - 기록 (0) | 2022.08.06 |
cocos2d-x 키보드,마우스 이벤트 등록 (0) | 2022.07.21 |
cocos2d-x Sprite (0) | 2022.07.20 |