카카오톡 오픈채팅방에서 초성퀴즈 봇이 있더군요
이거다 싶어서 퀴즈봇을 한번 만들어봤습니다.
퀴즈봇 설명
기본적인 명령어는 다음과 같습니다
명령어 | 설명 |
1help | 도움말을 출력합니다 |
1quiz | 퀴즈를 시작합니다 |
1a [정답] | 퀴즈의 정답을 맞춥니다 |
1ㅁ [정답] | 퀴즈의 정답을 맞춥니다 |
1pass | 현재 퀴즈를 패스합니다(총 세명 필요) |
1hint | 현재 퀴즈에 힌트를 출력합니다 |
1rank | 퀴즈 순위를 출력합니다 |
해당 봇은 방을 구분하여서 퀴즈가 생성되며, 퀴즈를 맞출때까지 다음문제로 넘어가지 않습니다. 다음 문제로 넘어가기 위해서는 1pass를 3명이 입력하면 답을 알려주고 넘어가게 됩니다.
사용자 편의상의 이유로 정답을 맞출때 1a, 1ㅁ명령어를 만들어 한영전환에 부담을 줄였습니다.
아래 영상은 미국주식방에서 실제 사용한 시연영상입니다
오픈채팅방에서 퀴즈봇을 만들고 싶다 하시면 한번 해보시길 강추드립니다
퀴즈봇 소스코드
소스코드를 그대로 봇에 넣어주시면 됩니다 봇 생성법을 잘모르시면 이글을 참고해주세요
function response(room, msg, sender, isGroupChat, replier, ImageDB, packageName) {
if (msg.startsWith('1help')) {
replier.reply(help());
}
if (msg.startsWith('1quiz')) {
replier.reply(get_quiz(room));
}
if (msg.startsWith('1a ')) {
let answer = msg.substr(3);
replier.reply(answer_quiz(room, answer, sender));
}
if (msg.startsWith('1ㅁ ')) {
let answer = msg.substr(3);
replier.reply(answer_quiz(room, answer, sender));
}
if (msg.startsWith('1pass')) {
replier.reply(pass_quiz(room, sender));
}
if (msg.startsWith('1hint')) {
replier.reply(hint_quiz(room));
}
if (msg.startsWith('1rank')) {
replier.reply(ranking(room));
}
}
function help() {
let msg = '(⊙_⊙)?봇 사용법\n' + '\u200b'.repeat(500);
const help_msg = [
'1help: 도움말을 출력합니다',
'1quiz: 퀴즈를 시작합니다',
'1a [정답]: 퀴즈의 정답을 맞춥니다',
'1ㅁ [정답]: 퀴즈의 정답을 맞춥니다',
'1pass: 현재 퀴즈를 패스합니다',
'1hint: 현재 퀴즈에 힌트를 출력합니다',
'1rank: 퀴즈 순위를 출력합니다',
];
msg += help_msg.join('\n');
return msg;
}
let sdcard = android.os.Environment.getExternalStorageDirectory().getAbsolutePath(); //절대경로
function save(originpath, content) {
// originpath는 sdcard/폴더/파일
var splited_originpath = originpath.split('/');
splited_originpath.pop();
var path = splited_originpath.join('/');
var folder = new java.io.File(path);
folder.mkdirs();
var file = new java.io.File(originpath);
var fos = new java.io.FileOutputStream(file);
var contentstring = new java.lang.String(content);
fos.write(contentstring.getBytes());
fos.close();
}
function read(originpath) {
var file = new java.io.File(originpath);
if (file.exists() == false) return null;
try {
var fis = new java.io.FileInputStream(file);
var isr = new java.io.InputStreamReader(fis);
var br = new java.io.BufferedReader(isr);
var temp_br = br.readLine();
var temp_readline = '';
while ((temp_readline = br.readLine()) !== null) {
temp_br += '\n' + temp_readline;
}
try {
fis.close();
isr.close();
br.close();
return temp_br;
} catch (error) {
return error;
}
} catch (error) {
return error;
}
}
let quiz_room = {};
let quiz_list = JSON.parse(read(sdcard + '/bot/quiz.json'));
let quiz_pass = {};
let user_score = JSON.parse(read(sdcard + '/bot/user.json'));
function quiz_make() {
let quiz = quiz_list[Math.floor(Math.random() * quiz_list.length)];
return quiz;
}
function quiz_exist(room) {
return quiz_room.hasOwnProperty(room);
}
function get_quiz(room) {
if (!quiz_room.hasOwnProperty(room)) {
quiz_room[room] = quiz_make();
}
let output = '문제: ' + quiz_room[room][0] + '\n';
output += '주제: ' + quiz_room[room][1];
return output;
}
function pass_quiz(room, sender) {
if (!quiz_exist(room)) {
return '아직 출제한 퀴즈가 없습니다.';
}
if (!quiz_pass.hasOwnProperty(room)) {
quiz_pass[room] = [];
}
let output = '';
if (!quiz_pass[room].includes(sender)) {
quiz_pass[room].push(sender);
output += sender + '님이 퀴즈를 패스하셨습니다.\n';
output += '총 3명이 패스를 하면 퀴즈가 넘어갑니다.\n';
output += '현재 패스한 사람: ' + quiz_pass[room].join(', ') + '\n';
output += '총 ' + quiz_pass[room].length + '명';
} else {
return sender + '님은 이미 패스하셨습니다.';
}
if (quiz_pass[room].length === 3) {
output = '!!문제를 패스합니다!!\n정답은 ' + quiz_room[room][3] + ' 이었습니다!';
delete quiz_room[room];
delete quiz_pass[room];
}
return output;
}
function hint_quiz(room) {
if (!quiz_exist(room)) {
return '아직 출제한 퀴즈가 없습니다.';
}
return '힌트: ' + quiz_room[room][2];
}
function answer_quiz(room, answer, sender) {
if (!quiz_exist(room)) {
return '아직 출제한 퀴즈가 없습니다.';
}
let output = '';
answer = answer.toUpperCase().replace(/ /g, "");
if (quiz_room[room][3] == answer) {
output = sender + '님\n!!정답입니다!!\n';
output += '정답은 "' + quiz_room[room][3] + '" 이었습니다!\n';
if (!user_score.hasOwnProperty(room)) {
user_score[room] = {};
}
if (!user_score[room].hasOwnProperty(sender)) {
user_score[room][sender] = 1;
} else {
user_score[room][sender] += 1;
}
save(sdcard + '/bot/user.json', JSON.stringify(user_score));
output += '점수: ' + user_score[room][sender];
delete quiz_room[room];
delete quiz_pass[room];
} else {
output = sender + '님\n!!오답입니다!!';
}
return output;
}
function ranking(room) {
let output = room + '방 랭킹 정보\n' + '\u200b'.repeat(500);
let score = [];
for (let key in user_score[room]) {
score.push([key, user_score[room][key]]);
}
score.sort(function (a, b) {
return b[1] - a[1];
});
for (let i = 0; i < score.length; i++) {
output += i + 1 + '등 ' + score[i][0] + ': ' + score[i][1] + '점\n';
}
return output;
}
이 코드를 복사 붙여넣기를 한 후 스크립트 리로드 할 경우 분명 에러가 날겁니다.
아직 세팅이 다 끝나지 않았기 때문입니다.
파일 세팅
이 소스코드는 두개의 json파일 정보를 입출력하여 활용합니다.
user.json, quiz.json으로 각각 유저의 퀴즈점수, 퀴즈 정보에 대하여 관리합니다.
각 파일을 만들어서 sd카드 위치를 기점으로 bot폴더를 생성한 후 그 안에 두 파일을 집어넣어 줍니다.
json에 대하여 전혀모른다면 이 사이트에서 기본기를 숙지해주세요.
user.json
{
}
초기에는 아무런 user정보도 없기 때문에 빈 객체를 생성해준다.
quiz.json
[
["대한민국 코스피 시가총액 1위인 기업이름은?(한글)", "주식", "국내 개미들이 가장 사랑하는 주식이기도 하다", "삼성전자"],
["대한민국의 벤처 기업·중견기업들에 안정적인 자금을 공급하기 위해 설립된 증권시장을 의미하는 단어는(한글)", "주식", "한국의 나스닥이라고 불린다", "코스닥"],
["국내 네이버에서 스크래치를 모델로하여 만든 블록코딩 교육 플랫폼 이름은?(한글)", "프로그래밍", "2015 개정 교육과정에 따라 교육용 프로그래밍 언어로 채택되어, 전국 초중생들이 배운다.", "엔트리"],
["도라에몽에게 도움을 받는 등장인물의 이름은?(한글)", "애니메이션", "매우 게으르며, 이슬이에게 집착한다", "노진구"],
["러시아의 독재자이지만 국민들에게 많은 사랑을 받는 대통령 이름은?(풀네임)", "정치/국제", "대선시기가 되면 그의 경쟁자들이 소리소문 없이 사라진다", "블라디미르푸틴"],
["2004년 넥슨에서 출시한 한국의 온라인 레이싱 게임으로 지금까지도 국민레이싱게임으로 불리는 게임 이름은?(한글)", "게임", "이 게임에서 드리프트와 부스터가 핵심 기술이다", "카트라이더"],
["2002년 위젯 스튜디오에서 제작하여 넥슨에서 유통하는 MMORPG로 SD 생김새의 캐릭터가 모험을 떠나는 2D 횡스크롤 게임 이름은?(한글)", "게임", "단풍잎", "메이플스토리"],
["2001년 넥슨에서 출시한 한국의 온라인 게임으로, 붐버맨에 영감을 받아 만들어진 게임이름은?(한글)", "게임", "캐쉬 아이템인 강퇴반사로 논란이 있었다", "크레이지아케이드"],
["2005년 넥슨에서 출신한 한국 FPS게임으로 게임의 제목이 '기습공격'을 뜻하는 게임이름은?(한글)", "게임", "후속작인 2가 출시 2개월만에 대차게 망했다", "서든어택"],
["네오플에서 제작하여 2005년에 출시한 스크롤 액션 도트 게임 이름은?(한글)", "게임", "어떤 사건을 계기로 대표적인 공익게임이 되었다", "던전앤파이터"],
["2015년에 넥슨에서 출시한 MMORPG로 동화풍 그래픽에 높은 자유도를 특징으로 하는 게임 이름은?(한글)", "게임", "온갖 버그로 똥나무 버그망겜이라 불린다.", "트리오브세이비어"],
["ㅇㄸㄱㅎㅎㅂㅂㅁ", "라면/초성퀴즈", "오, 뚜, 흥", "오뚜기함흥비빔면"],
["ㅅㅇㅂㅋㅇㄴ", "치킨/초성퀴즈", "굽네치킨", "스윗볼케이노"]
]
quiz.json은 2차원 배열로 이루어져 있는데 안에 [문제, 주제, 힌트, 정답] 순으로 데이터가 구성되어 있습니다
위에 코드는 예시로 몇개 집어넣은것이고, 본인이 문제를 추가하거나 삭제하여서 자유자제로 사용하면 됩니다.
모든 세팅이 끝나면 quiz.json만 수정하여 퀴즈봇을 활용하면 된다는 것입니다.
정답을 작성하실때 띄워쓰기X, 영어는 대문자로 작성해주세요(답과 비교할때 answer을 자동으로 띄워쓰기 제거하고 대문자로 변환하여 비교합니다)
sd카드의 루트폴더에 bot이라는 폴더를 생성 후 만들어둔 두개의 json파일을 옮겨줍니다.
다 옮겨졌으면 다시 자동응답봇을 켜서 스크립트 리로드를 해봅시다.
에러 없이 정상작동한다면 모든 세팅이 완벽히 끝났습니다.
마지막으로 디버깅룸에서 명령어 작동을 확인해봅시다.
'웹 > Javascript' 카테고리의 다른 글
카카오톡 챗봇 코인 정보봇 만들기 (3) | 2021.12.24 |
---|---|
카카오톡 챗봇 만들기(Javascript) (2) | 2021.12.24 |