BASIC4MCU | 질문게시판 | Atmega128과 도트 매트릭스질문
페이지 정보
작성자 탈모공학자 작성일2023-12-01 01:36 조회1,286회 댓글1건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=23465
본문
도트매트릭스를 이용해서 게임을 만드는 중인데, 지금 막힌 부분이 한 플레이어당 9개씩 돌을 놓고 나서 18개를 다 놓으면 그다음부터는 자기가 놓은 도트를 선택해서 한칸씩 옮길 수 있어야하는데 그게 너무 어렵습니다. 스위치는 새로 추가해도 되긴 하는데 사실 지금 여기서 아무리 해봐도 감이 안잡혀요. 아니면 내가 착수한 도트를 다시 선택해서 움직이게만 된다면 좀 진전이 있을텐데 말이죠..
#define F_CPU 16E6
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "TWI.h"
#include "Dot_I2C.h"
#define MAX_STONES 18 // 최대 돌의 개수
#define NUM_VALID_POSITIONS 24 // 착수 가능한 위치의 개수
// 착수 가능한 위치 좌표
uint8_t validPositions[NUM_VALID_POSITIONS][2] = {
{1, 1}, {4, 1}, {7, 1},
{2, 2}, {4, 2}, {6, 2},
{3, 3}, {4, 3}, {5, 3},
{1, 4}, {2, 4}, {3, 4}, {5, 4}, {6, 4}, {7, 4},
{3, 5}, {4, 5}, {5, 5},
{2, 6}, {4, 6}, {6, 6},
{1, 7}, {4, 7}, {7, 7}
};
typedef uint8_t DOT_I2C_Color; // 색상 유형 정의
#define PLAYER1_COLOR DOT_I2C_RED
#define PLAYER2_COLOR DOT_I2C_GREEN
volatile unsigned char currentRow = 1;
volatile unsigned char currentCol = 1;
volatile uint8_t putPressed = 0; // 착수 버튼
uint8_t currentPlayer = 1; // 1 또는 2
uint8_t stoneRows[MAX_STONES];
uint8_t stoneCols[MAX_STONES];
uint8_t stoneCount = 0;
void updateDisplay() {
DOT_I2C_Clear();
// 착수한 돌들 표시
for (uint8_t i = 0; i < stoneCount; ++i) {
DOT_I2C_Color stoneColor = (i % 2 == 0) ? PLAYER1_COLOR : PLAYER2_COLOR;
DOT_I2C_DrawPixel(stoneCols[i], stoneRows[i], stoneColor);
}
// 현재 차례의 돌 표시
DOT_I2C_DrawPixel(currentCol, currentRow, (currentPlayer == 1) ? PLAYER1_COLOR : PLAYER2_COLOR);
DOT_I2C_WriteDisplay();
}
void putStone() {
if (stoneCount >= MAX_STONES) {
return; // 착수 가능 돌 개수 초과 시 함수 종료
}
// 착수 가능한 위치인지 확인
for (uint8_t i = 0; i < NUM_VALID_POSITIONS; ++i) {
if (validPositions[i][0] == currentCol && validPositions[i][1] == currentRow) {
// 확인할 변수
uint8_t positionOccupied = 0;
// 이미 돌이 있는지 확인
for (uint8_t j = 0; j < stoneCount; ++j) {
if (stoneCols[j] == currentCol && stoneRows[j] == currentRow) {
positionOccupied = 1;
break;
}
}
// 이미 돌이 있는 위치라면 아무 동작도 수행하지 않음
if (positionOccupied) {
break;
}
// 착수한 돌의 위치 저장
stoneRows[stoneCount] = currentRow;
stoneCols[stoneCount] = currentCol;
// 착수한 플레이어에 따라 돌의 색상 결정
DOT_I2C_Color stoneColor = (currentPlayer == 1) ? PLAYER1_COLOR : PLAYER2_COLOR;
// 저장된 돌의 개수 증가
++stoneCount;
// 돌을 그릴 때 색상 적용
DOT_I2C_DrawPixel(currentCol, currentRow, stoneColor);
// 디스플레이 업데이트
DOT_I2C_WriteDisplay();
// 차례 교체
currentPlayer = (currentPlayer == 1) ? 2 : 1;
// 표시 업데이트
updateDisplay();
break;
}
}
}
ISR(INT4_vect) {
// 왼쪽 스위치 눌림
if (currentCol == 4 && currentRow == 1) {
currentCol = 1;
} else if (currentCol == 7 && currentRow == 1) {
currentCol = 4;
} else if (currentCol == 7 && currentRow == 7) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 7) {
currentCol = 1;
} else if (currentCol == 4 && currentRow == 2) {
currentCol = 2;
} else if (currentCol == 6 && currentRow == 2) {
currentCol = 4;
} else if (currentCol == 6 && currentRow == 6) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 6) {
currentCol = 2;
} else if (currentCol == 2 && currentRow == 4) {
currentCol = 1;
} else if (currentCol == 3 && currentRow == 4) {
currentCol = 2;
} else if (currentCol == 7 && currentRow == 4) {
currentCol = 6;
} else if (currentCol == 6 && currentRow == 4) {
currentCol = 5;
} else if (currentCol == 4 && currentRow == 3) {
currentCol = 3;
} else if (currentCol == 5 && currentRow == 3) {
currentCol = 4;
} else if (currentCol == 5 && currentRow == 5) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 5) {
currentCol = 3;
}
updateDisplay();
_delay_ms(270);
}
ISR(INT5_vect) {
// 오른쪽 스위치 눌림
if (currentCol == 1 && currentRow == 1) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 1) {
currentCol = 7;
} else if (currentCol == 1 && currentRow == 7) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 7) {
currentCol = 7;
} else if (currentCol == 2 && currentRow == 2) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 2) {
currentCol = 6;
} else if (currentCol == 2 && currentRow == 6) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 6) {
currentCol = 6;
} else if (currentCol == 2 && currentRow == 4) {
currentCol = 3;
} else if (currentCol == 1 && currentRow == 4) {
currentCol = 2;
} else if (currentCol == 6 && currentRow == 4) {
currentCol = 7;
} else if (currentCol == 5 && currentRow == 4) {
currentCol = 6;
} else if (currentCol == 3 && currentRow == 3) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 3) {
currentCol = 5;
} else if (currentCol == 3 && currentRow == 5) {
currentCol = 4;
} else if (currentCol == 4 && currentRow == 5) {
currentCol = 5;
}
updateDisplay();
_delay_ms(270);
}
ISR(INT2_vect) {
// 위쪽 스위치 눌림
if (currentCol == 1 && currentRow == 7) {
currentRow = 4;
} else if (currentCol == 1 && currentRow == 4) {
currentRow = 1;
} else if (currentCol == 4 && currentRow == 3) {
currentRow = 2;
} else if (currentCol == 4 && currentRow == 2) {
currentRow = 1;
} else if (currentCol == 6 && currentRow == 4) {
currentRow = 2;
} else if (currentCol == 6 && currentRow == 6) {
currentRow = 4;
} else if (currentCol == 2 && currentRow == 4) {
currentRow = 2;
} else if (currentCol == 2 && currentRow == 6) {
currentRow = 4;
} else if (currentCol == 7 && currentRow == 7) {
currentRow = 4;
} else if (currentCol == 7 && currentRow == 4) {
currentRow = 1;
} else if (currentCol == 3 && currentRow == 5) {
currentRow = 4;
} else if (currentCol == 3 && currentRow == 4) {
currentRow = 3;
} else if (currentCol == 5 && currentRow == 5) {
currentRow = 4;
} else if (currentCol == 5 && currentRow == 4) {
currentRow = 3;
} else if (currentCol == 4 && currentRow == 7) {
currentRow = 6;
} else if (currentCol == 4 && currentRow == 6) {
currentRow = 5;
}
updateDisplay();
_delay_ms(270);
}
ISR(INT3_vect) {
// 아래쪽 스위치 눌림
if (currentCol == 1 && currentRow == 1) {
currentRow = 4;
} else if (currentCol == 1 && currentRow == 4) {
currentRow = 7;
} else if (currentCol == 7 && currentRow == 1) {
currentRow = 4;
} else if (currentCol == 7 && currentRow == 4) {
currentRow = 7;
} else if (currentCol == 4 && currentRow == 1) {
currentRow = 2;
} else if (currentCol == 4 && currentRow == 2) {
currentRow = 3;
} else if (currentCol == 4 && currentRow == 5) {
currentRow = 6;
} else if (currentCol == 4 && currentRow == 6) {
currentRow = 7;
} else if (currentCol == 6 && currentRow == 2) {
currentRow = 4;
} else if (currentCol == 6 && currentRow == 4) {
currentRow = 6;
} else if (currentCol == 2 && currentRow == 2) {
currentRow = 4;
} else if (currentCol == 2 && currentRow == 4) {
currentRow = 6;
} else if (currentCol == 3 && currentRow == 3) {
currentRow = 4;
} else if (currentCol == 3 && currentRow == 4) {
currentRow = 5;
} else if (currentCol == 5 && currentRow == 3) {
currentRow = 4;
} else if (currentCol == 5 && currentRow == 4) {
currentRow = 5;
}
updateDisplay();
_delay_ms(270);
}
ISR(INT6_vect) {
// 착수 스위치 눌림
putPressed = 1;
}
int main() {
TWI_Init();
DOT_I2C_Init();
// 외부 인터럽트 설정
EICRA = (1 << ISC01) | (1 << ISC11) | (1 << ISC21) | (1 << ISC31);
EIMSK = (1 << INT4) | (1 << INT5) | (1 << INT2) | (1 << INT3) | (1 << INT6);
sei(); // 전역적으로 인터럽트 활성화
while (1) {
// 착수 버튼이 눌렸을 때만 착수
if (putPressed) {
putStone();
putPressed = 0;
}
_delay_ms(200); // 딜레이 추가
}
}
댓글 1
조회수 1,286master님의 댓글
master 작성일
복잡한 코드는 남이 도와드리기 어렵습니다.
복잡할 수록 코딩하는 시간보다 고민하는 시간이 많아야 합니다.