알고리즘 모음(C++)
2021 충북 컴퓨터 꿈나무 축제 기출문제 - 중등부(지역대회, 아두이노) 본문
2021 충북컴퓨터꿈나무 축제 중등부 지역대회 기출문제 답안입니다.
필수 해결 요소는 전부 구현했으며, 창의적 문제 해결에서 예시 1, 2,3,5번을 구현했습니다.
남은 예시는 어렵지 않기에 밑의 코드를 이해하면 쉽게 구현할 수 있습니다.
문제 파일입니다.
문제를 읽어보지 않으셨다면 보시길 바랍니다.
제가 구현한 회로도입니다.
코드를 구현하기 전에 빨간색이 포함된 색을 표현할 때, 빨간색의 세기가 강해 다른 색이 나타나지 못합니다.
따라서 빨간색의 세기를 맞춰줘야합니다.
저는 빨간색 부분에 약 150옴 정도의 저항을 하나 연결해 세기를 낮춰줬습니다. 추가로 연결하는 저항의 세기는 다를 수 있음으로 찾아보시는걸 추천합니다.
먼저 구현해야할 부분은 색을 표현하는 것입니다.
문제에서 주어진 색을 Red, Green, Blue, Yellow, Magenta, Turquoise, White 임으로 각각에 맞게 RGB를 켜주면 됩니다.
코드에서는 색 이름이 함수 이름과 같음으로 참고하시길 바랍니다.
여기에서 3색 LED 3개는 같은 색을 나타냅니다. 따라서 2차원 배열을 통해 LED의 핀 번호를 저장한 뒤, 매개변수를 통해 쉽게 원하는 3색 LED를 킬 수 있습니다.
다음은 토글 스위치입니다.
스위치를 눌러 정답이 맞는 지를 확인해야합니다.
이때 스위치는 눌렀다는 것은 한번만 인식해야 함으로 토글 스위치로 만들어줍니다.
해당 스위치 코드는 아두이노에서 파일 -> 예제 -> digital -> statechangedetection에서 찾을 수 있습니다.
코드에서는 Sw_1(), Sw_2() 함수입니다.
질문을 구현하는 부분입니다.
Q_1() ~ Q_6()는 거의 같은 내용입니다.
Q_1()을 예시로 설명하면 먼저 질문을 맞추기 전에 두개의 스위치의 누른 횟수를 초기화해서 정답을 고를 수 있게 해줍니다.
다음으로 while(1)을 통해 답을 고를 때까지 다음 질문으로 넘어가지 못하게 합니다.
2개의 스위치를 통해 대답이 들어왔다면 정답과 맞는지 비교합니다. -> 각각의 스위치의 누른 횟수를 통해 어떤 대답을 했는지 알 수 있습니다.
정답이 맞다면, sum을 문제의 점수만큼 올려 총 점수를 구한 뒤, 정답 소리를 울려줍니다.
정답이 아니라면, 틀렸다는 소리를 울려줍니다.
마지막으로 랜덤으로 문제를 주는 방법입니다.
랜덤으로 문제를 주되, 중복된 문제를 주면 안됩니다. 따라서 배열 하나를 만든 뒤, 문제가 하나 주어졌다면 해당 문제를 다시 나오지 못하도록 배열에 특정한 값을 대입합니다.
랜덤한 값이 6번 나왔다면, 모든 질문이 나온 것임으로 총 점수를 출력해줍니다.
자세한 것은 코드를 참고해주세요
//첫번째 3색 LED
// A0 -> Blue, A1 -> Green, A2 -> Red
//두번째 3색 LED
// A3 -> Blue, A4 -> Green, A5 -> Red
//세번째 3색 LED
// 3 -> Blue, 5 -> Green, 6 -> Red
// 3색 LED에서 Red의 색이 강하기 때문에 저항을 따로 연결해서 Red의 세기를 낮춰준다.
int check[7] = {0, 0, 0, 0, 0, 0, 0}; //문제가 랜덤하게 나올때 똑같은 것이 나오지 못하도록 해준다
int button_1 = 0;
int lastbutton_1 = 0;
int cnt_1 = 0;
int button_2 = 0;
int lastbutton_2 = 0;
int cnt_2 = 0;
int sum = 0;
int Round = 0;
int maxi = 0;
int Led[3][3] = { //3개의 3색 LED를 효율적으로 관리하기 위해 2차원 배열로 만듦
{A0, A1, A2},
{A3 , A4, A5},
{3, 5, 6}
};
void show_led();
void setup() {
Serial.begin(9600); //시리얼 모니터 사용
randomSeed(analogRead(0)); //무작위 난수를 얻기 위함
pinMode(13, INPUT); // SW
pinMode(12, INPUT); //SW
show_led(); // 색 조합은 한번만 나와야하니 setup에서 실행
}
// 토글 스위치 구현
void Sw_1() {
button_1 = digitalRead(13);
if (button_1 != lastbutton_1) {
if (button_1 == HIGH) {
cnt_1++;
}
delay(50);
}
lastbutton_1 = button_1;
}
void Sw_2() {
button_2 = digitalRead(12);
if (button_2 != lastbutton_2) {
if (button_2 == HIGH) {
cnt_2++;
}
delay(50);
}
lastbutton_2 = button_2;
}
//
//문제에서 주어진 색깔을 구현
void Red(int x) {
analogWrite(Led[x - 1][0], 0);
analogWrite(Led[x - 1][1], 0);
analogWrite(Led[x - 1][2], 255);
}
void Blue(int x) {
analogWrite(Led[x - 1][0], 255);
analogWrite(Led[x - 1][1], 0);
analogWrite(Led[x - 1][2], 0);
}
void Green(int x) {
analogWrite(Led[x - 1][0], 0);
analogWrite(Led[x - 1][1], 255);
analogWrite(Led[x - 1][2], 0);
}
void Yellow(int x) {
analogWrite(Led[x - 1][0], 0);
analogWrite(Led[x - 1][1], 255);
analogWrite(Led[x - 1][2], 255);
}
void Magenta(int x) { // 자홍색
analogWrite(Led[x - 1][0], 255);
analogWrite(Led[x - 1][1], 0);
analogWrite(Led[x - 1][2], 255);
}
void Turquoise(int x) { // 청록색
analogWrite(Led[x - 1][0], 255);
analogWrite(Led[x - 1][1], 255);
analogWrite(Led[x - 1][2], 0);
}
void White(int x) {
analogWrite(Led[x - 1][0], 255);
analogWrite(Led[x - 1][1], 255);
analogWrite(Led[x - 1][2], 255);
}
//
//시작할 때 보여주는 색 조합
void show_led() {
//설명을 하고 시작하기 때문에 해당 코드에서 delay 사용해도 무방하다
Serial.println("Red + Green = Yellow");
Red(1);
delay(1000);
Green(1);
delay(1000);
Yellow(1);
delay(1500);
//////////////////////////////////////////////////////////
Serial.println("Red + Blue = Magenta");
Red(1);
delay(1000);
Blue(1);
delay(1000);
Magenta(1);
delay(1500);
/////////////////////////////////////////////////////////
Serial.println("Green + Blue = Turquoise");
Green(1);
delay(1000);
Blue(1);
delay(1000);
Turquoise(1);
delay(1500);
////////////////////////////////////////////////////////
Serial.println("Red + Green + Blue = White");
Red(1);
delay(1000);
Green(1);
delay(1000);
Blue(1);
delay(1000);
White(1);
delay(1500);
////////////////////////////////////////////////////////
Serial.println("Red + Turquoise = White");
Red(1);
delay(1000);
Turquoise(1);
delay(1000);
White(1);
delay(1500);
////////////////////////////////////////////////////////
Serial.println("Green + Magenta = White");
Green(1);
delay(1000);
Magenta(1);
delay(1000);
White(1);
delay(1500);
///////////////////////////////////////////////////////
Serial.println("Blue + Yellow = White");
Blue(1);
delay(1000);
Yellow(1);
delay(1000);
White(1);
delay(1500);
///////////////////////////////////////////////////////
analogWrite(A0, 0);
analogWrite(A1, 0);
analogWrite(A2, 0);
}
void print_sum() {
Serial.print("현재 점수는");
Serial.print(sum);
Serial.println("입니다");
}
void success_sound() {
noTone(8);
tone(8, 440, 200);
delay(200);
}
void fail_sound() {
noTone(8);
tone(8, 523, 300);
delay(300);
}
void random_led_1() {
analogWrite(Led[0][0], random(0, 255));
analogWrite(Led[0][1], random(0, 255));
analogWrite(Led[0][2], random(0, 255));
}
//문제 1~6
void Q_1() {
Serial.println("빨간색과 초록색을 합성하면?");
Serial.println("두개 중 맞는 것을 선택하시오");
Yellow(2);
Turquoise(3);
cnt_1 = 0;
cnt_2 = 0;
while (1) {
Sw_1();
Sw_2();
if (cnt_1 > 0) {
Serial.println("맞았습니다");
sum += 5;
print_sum();
success_sound();
break;
}
else if (cnt_2 > 0) {
Serial.println("틀렸습니다");
fail_sound();
print_sum();
break;
}
}
}
void Q_2() {
Serial.println("빨간색과 파란색을 합성하면?");
Serial.println("두개 중 맞는 것을 선택하시오");
Turquoise(2);
Magenta(3);
cnt_1 = 0;
cnt_2 = 0;
while (1) {
Sw_1();
Sw_2();
if (cnt_2 > 0) {
Serial.println("맞았습니다");
success_sound();
sum += 5;
print_sum();
break;
}
else if (cnt_1 > 0) {
Serial.println("틀렸습니다");
fail_sound();
print_sum();
break;
}
}
}
void Q_3() {
Serial.println("초록색과 파란색을 합성하면?");
Serial.println("두개 중 맞는 것을 선택하시오");
Red(2);
Turquoise(3);
cnt_1 = 0;
cnt_2 = 0;
while (1) {
Sw_1();
Sw_2();
if (cnt_2 > 0) {
Serial.println("맞았습니다");
success_sound();
sum += 5;
print_sum();
break;
}
else if (cnt_1 > 0) {
Serial.println("틀렸습니다");
fail_sound();
print_sum();
break;
}
}
}
void Q_4() {
Serial.println("빨간색의 보색은?");
Serial.println("두개 중 맞는 것을 선택하시오");
Turquoise(2);
Blue(3);
cnt_1 = 0;
cnt_2 = 0;
while (1) {
Sw_1();
Sw_2();
if (cnt_1 > 0) {
Serial.println("맞았습니다");
success_sound();
sum += 10;
print_sum();
break;
}
else if (cnt_2 > 0) {
Serial.println("틀렸습니다");
fail_sound();
print_sum();
break;
}
}
}
void Q_5() {
Serial.println("초록색의 보색은?");
Serial.println("두개 중 맞는 것을 선택하시오");
Yellow(2);
Magenta(3);
cnt_1 = 0;
cnt_2 = 0;
while (1) {
Sw_1();
Sw_2();
if (cnt_2 > 0) {
Serial.println("맞았습니다");
success_sound();
sum += 10;
print_sum();
break;
}
else if (cnt_1 > 0) {
Serial.println("틀렸습니다");
fail_sound();
print_sum();
break;
}
}
}
void Q_6() {
Serial.println("파란색의 보색은?");
Serial.println("두개 중 맞는 것을 선택하시오");
Yellow(2);
Red(3);
cnt_1 = 0;
cnt_2 = 0;
while (1) {
Sw_1();
Sw_2();
if (cnt_1 > 0) {
Serial.println("맞았습니다");
success_sound();
sum += 10;
print_sum();
break;
}
else if (cnt_2 > 0) {
Serial.println("틀렸습니다");
fail_sound();
print_sum();
break;
}
}
}
//
void Question(int x) {
if (x == 1) {
Q_1();
}
else if (x == 2) {
Q_2();
}
else if (x == 3) {
Q_3();
}
else if (x == 4) {
Q_4();
}
else if (x == 5) {
Q_5();
}
else {
Q_6();
}
}
void loop() {
int x = random(1, 7);
if (check[x] == 0) { //x를 통해 random한 값을 받을 뒤, 해당 값이 이전에 나왔는지를 확인한다.
Question(x);
check[x] = 1; // 똑같은 문제가 나오지 못하도록 1을 대입해준다.
Round++;
}
if (Round == 6) { // 모든 문제가 전부 나왔을 경우
Serial.println("////////////////////////////");
Serial.print("최종점수는 ");
Serial.print(sum);
Serial.println("입니다.");
if (maxi < sum) {
random_led_1();
maxi = sum;
noTone(8);
tone(8, 440, 200);
delay(100);
noTone(8);
tone(8, 660, 200);
delay(100);
noTone(8);
tone(8, 300, 200);
delay(100);
}
Serial.print("현재까지 최대 점수는 ");
Serial.print(maxi);
Serial.println(" 입니다.");
Serial.println("////////////////////////////");
for (int i = 0; i <= 2; i++) {
for (int j = 0; j < 3; j++) {
analogWrite(Led[i][j] , 0);
}
}
for (int i = 1; i <= 6; i++) {
check[i] = 0;
}
sum = 0;
Round = 0;
Serial.println("////////////////////////////");
Serial.println("새로운 라운드 시작");
Serial.println("////////////////////////////");
}
}
문제를 이해하고 코드를 전부 구현하는데 까지 걸린 시간은 대략 2시간 정도입니다.
중등부 문제이지만 구현자체는 어렵지 않았습니다.
3색 LED에서 정확한 색을 어떻게 나타낼 것인가를 해결하는 것에서 차이가 생겼을 것으로 예상됩니다.
질문이 있으시다면 댓글을 남겨주세요
'아두이노 대회(충북)' 카테고리의 다른 글
2019 충북 컴퓨터 꿈나무 축제 기출문제 - 중등부(지역대회, 아두이노) (0) | 2022.07.21 |
---|---|
2021 충북 컴퓨터 꿈나무 축제 기출문제 - 중등부(도대회, 아두이노) (0) | 2022.07.20 |