[Программирование] Странные шахматы как тестовое задание
Автор
Сообщение
news_bot ®
Стаж: 7 лет 2 месяца
Сообщений: 27286
Добрый вечер хаброжители!Сегодня я предоставлю вашему вниманию небольшую статью не связанную с моими предыдущими статьями. Где-то более года назад мне пришлось делать одно тестовое задание чтобы устроится на работу. Выполнил я его в срок, но конкуренция была большая и скорее всего взяли человека который сделал его с помощью рекомендованных технологий и красочнее.Суть задачи, есть доска 8 на 8 клеток. У игрока есть 9 шашек они расположены в углу доски в квадрате 3 на 3, у противника тоже столько же шашек и они расположены симметрично по диагонали в другом углу в квадрате 3 на 3. Каждый игрок ходит по очереди, нужно дойти шашками на места изначального положения соперника через всю доску, кто первый дошел тот и победил. Ходить можно только на пустые клетки и только вверх, вниз, влево и вправо(по диагонали нельзя!).
Управление я добавил мышью, а играть против компьютерного алгоритма. Черные - человек, белые - ИИ.Помимо всего прочего изначально необходимо отрисовать доску, шашки и делать манипуляции с полем.Немного кода для наглядности:
Game::Game()
{
run = true;//флаг признак нажатия кнопки выхода F5
Matrix = new int* [8];//Поле 64 ячейки - значения 0 - для пустой ячейки, для игрока каждая пешка-шашка от 1 до 9, для компьютера значения в матрице от 10 до 18
for (int i = 0; i < 8; i++)
Matrix[i] = new int[8];
//Квадраты координат нужны чтобы программа знала какие ячейки над указателем мыши, 64 квадрата
QuadCoorXleft = new int* [8];//каждой ячейки матрицы Matrix соответстует квадрат координат для мыши xleft означает левую координату x
QuadCoorXright = new int* [8];//xright - правая x
QuadCoorYdown = new int* [8];//верхняя y координата
QuadCoorYup = new int* [8];//нижняя y координата
for (int i = 0; i < 8; i++)
{
QuadCoorXleft[i] = new int[8];
QuadCoorXright[i] = new int[8];
QuadCoorYdown[i] = new int[8];
QuadCoorYup[i] = new int[8];
}
//Координаты пешек для отрисовки
ChessX = new double[18];//X
ChessY = new double[18];//Y
//Выделяемая пешка ее координаты и значения
ActiveX = -1;//X
ActiveY = -1;//Y
Active = -1;//Value
firstplayer = true;//флаг того что можете игрок 1й ходить
secondplayer = false;//флаг того что можете игрок 2й ходить
ai = new bool[18];//ячейки флаги того что пешка на финишной позиции
chessai tmp;
for (int i = 0; i < 18; i++)
{
ai[i] = false;
if (i > 8)
{
tmp.ai = ai[i];
tmp.value = i+1;
Ai.push_back(tmp);//Вектор с флагами финиша каждой пешки для искуственного интеллекта
}
}
aicountfirstrow = 0;//счетчик кол-ва пешек ИИ(искуственного интеллекта) на верхней строчке(0-я)
aicountsecondrow = 0;//счетчик кол-ва пешек ИИ на предверхней строчке(1-я)
aicountthirdrow = 0;//счетчик кол-ва пешек ИИ на предпредверхней строчке(2-я)
}
Для отрисовки и захвата мыши используется библиотеки OpenGL и SDL2.
void Draw_Circle()
{
//Отрисовка круга(пешек-шахмат) черного
for (int i = 0; i <= 50; i++) {
float a = (float)i / 50.0f * 3.1415f * 2.0f;
glVertex2f(cos(a), sin(a));
}
}
void Draw_Circle_Fill()
{
//Отрисовка круга(пешек-шахмат) белого
for (int i = 0; i <= 50; i++) {
float a = (float)i / 50.0f * 3.1415f * 2.0f;
glVertex2f(0.0, 0.0);
glVertex2f(cos(a), sin(a));
}
}
Самое удобное что можно использовать glTranslatef чтобы заполнить доску шашками с перемещениями
...
for (int i = 0; i < 9; i++)
{
glPushMatrix();
glTranslatef(ChessX[i], ChessY[i], 0);
glScalef(0.05, 0.05, 1);
glBegin(GL_LINE_LOOP);
Draw_Circle();
glEnd();
glPopMatrix();
}
//Рисуем белые пешки ИИ
for (int i = 9; i < 18; i++)
{
glPushMatrix();
glTranslatef(ChessX[i], ChessY[i], 0);
glScalef(0.05, 0.05, 1);
glBegin(GL_LINES);
Draw_Circle_Fill();
glEnd();
glPopMatrix();
}
...
Ходы игрока:
void Game::Move_Up()
{
//Ход игрока вверх
if (Active > 0 && ActiveX != 0 && Matrix[ActiveX-1][ActiveY] == 0)//Если выделенная пешка и не самая верхняя строчка и ячейка выше пустая
{
Matrix[ActiveX-1][ActiveY] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке выше текущюю(выделенную пешку)
Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую
ChessY[Active-1] += 0.2;//перемещаем координату У пешки вверх для отрисовки
ActiveX = -1;//стираем координаты выделенной пешки
ActiveY = -1;//стираем координаты выделенной пешки
Active = -1;//делаем неактивной текущую выделенную фигуру
std::cout << " Player MoveUp " << Active << std::endl;
firstplayer = false;
secondplayer = true;//меняем флаги хода от игрока к ИИ
}
}
void Game::Move_Down()
{
//Ход игрока вниз
if (Active > 0 && ActiveX != 7 && Matrix[ActiveX+1][ActiveY] == 0)//Если выделенная пешка и не самая нижняя строчка и ячейка ниже пустая
{
Matrix[ActiveX+1][ActiveY] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке ниже текущюю(выделенную пешку)
Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую
ChessY[Active-1] -= 0.2;//перемещаем координату У пешки вниз для отрисовки
ActiveX = -1;//стираем координаты выделенной пешки
ActiveY = -1;//стираем координаты выделенной пешки
Active = -1;//делаем неактивной текущую выделенную фигуру
std::cout << "Player MoveDown " << Active << std::endl;
firstplayer = false;
secondplayer = true;//меняем флаги хода от игрока к ИИ
}
}
void Game::Move_Right()
{
//Ход игрока вправо
if (Active > 0 && ActiveY != 7 && Matrix[ActiveX][ActiveY+1] == 0)//Если выделенная пешка и не самая правая строчка и ячейка справа пустая
{
Matrix[ActiveX][ActiveY+1] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке справа текущюю(выделенную пешку)
Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую
ChessX[Active-1] += 0.2;//перемещаем координату Х пешки вправо для отрисовки
ActiveX = -1;//стираем координаты выделенной пешки
ActiveY = -1;//стираем координаты выделенной пешки
Active = -1;//делаем неактивной текущую выделенную фигуру
std::cout << "MoveRight " << Active << std::endl;
firstplayer = false;
secondplayer = true;//меняем флаги хода от игрока к ИИ
}
}
void Game::Move_Left()
{
//Ход игрока влево
if (Active > 0 && ActiveY != 0 && Matrix[ActiveX][ActiveY-1] == 0)//Если выделенная пешка и не самая левая строчка и ячейка слева пустая
{
Matrix[ActiveX][ActiveY-1] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке слева текущюю(выделенную пешку)
Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую
ChessX[Active-1] -= 0.2;//перемещаем координату Х пешки влево для отрисовки
ActiveX = -1;//стираем координаты выделенной пешки
ActiveY = -1;//стираем координаты выделенной пешки
Active = -1;//делаем неактивной текущую выделенную фигуру
std::cout << "MoveLeft " << Active << std::endl;
firstplayer = false;
secondplayer = true;//меняем флаги хода от игрока к ИИ
}
}
Ходы компьютера почти аналогичны ходам игрока, в конце будет ссылка на полный код игры, если кому интересно.
void Game::ReccurentWalk()
{
//Реккурентный ход ИИ
current = -1, currentI = -1, currentJ = -1;//изначально выделенная пешка не определена
for (int i = 0; i < Ai.size(); i++)//поиск по массиву
if (!Ai[i].ai)//если не завершены ходы для конкретных пешек
{
if (Check_MoveUp(Ai[i].value) || Check_MoveLeft(Ai[i].value))//Можно ли походить вверх или влево?
{
current = Ai[i].value;//запоминаем текущую пешку
break;
}
else
{
//Если походить нельзя стираем из массива ходов пешку
std::vector<chessai>::iterator position = std::find_if(Ai.begin(), Ai.end(), find_s(Ai[i].value));
if (position != Ai.end()) // == vector.end() means the element was not found
Ai.erase(position);
}
}
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (Matrix[i][j] == current)//ищем в матрице пешку и запоминаем индексы
{
currentI = i;
currentJ = j;
break;
}
if (currentI != -1 && currentJ != -1)//если какая либо найдена ходим либо вверх либо влево
{
if (!Move_UpAI(currentI, currentJ))
if (!Move_LeftAI(currentI, currentJ))
{
ReccurentWalk();
}
}
else
{
//если не найдена заполняем массив ходов снова пешками
chessai tmp;
for (int i = 0; i < 18; i++)
{
ai[i] = false;
if (i > 8)
{
tmp.ai = ai[i];
tmp.value = i + 1;
Ai.push_back(tmp);
}
}
//ищем ту которая может походить вправо или вниз
for (int i = 0; i < Ai.size(); i++)
if (!Ai[i].ai)
{
if (Check_MoveRight(Ai[i].value) || Check_MoveDown(Ai[i].value))
{
current = Ai[i].value;
break;
}
else
{
//если не может то стираем из массива
std::vector<chessai>::iterator position = std::find_if(Ai.begin(), Ai.end(), find_s(Ai[i].value));
if (position != Ai.end()) // == Vector.end() means the element was not found
Ai.erase(position);
}
}
//ищем ее индексы в матрице
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (Matrix[i][j] == current)
{
currentI = i;
currentJ = j;
break;
}
//ходим вправо или вниз
if(!Move_RightAI(currentI, currentJ))
if (!Move_DownAI(currentI, currentJ))
{
std::cout <<"Artificial Intellegence asked: WTF?" << std::endl;
}
}
chessai tmp;
if(Ai.empty())//если список ходов пуст заполняем снова всеми
for (int i = 0; i < 18; i++)
{
ai[i] = false;
if (i > 8)
{
tmp.ai = ai[i];
tmp.value = i + 1;
Ai.push_back(tmp);
}
}
}
Ну и собственно опишу словами, что делает ИИ. Он собирает три пешки вверху на 0-ой строке и если ходить нельзя влево, то двигает вверх остальные 3 пешки на 1 строку, аналогично и на 2-ю строку. Если ходить влево и вверх нельзя, то он берет любую шашку и двигает либо вниз либо вправо если можно конечно, то есть стремится всегда двигать влево или вверх( при условии что выше меньше трёх шашек в строке).Ну собственно и геймплей:Извините, данный ресурс не поддреживается. :( И ссылка на исходный код.
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, IT-инфраструктура, Управление проектами, Kubernetes] Интервью с Марселем Ибраевым о распиле монолита или «Успех распила монолита – грамотный менеджмент»
- [Программирование, Хакатоны, Логические игры] Секретное агентство Undercover — операция ESCAPE THE ROOM
- [Программирование, DevOps, Kubernetes] Kubernetes Headless Service: А если Pod исчез?
- [JavaScript, Программирование, Разработка систем связи, Облачные сервисы] Скрываем номера курьеров и клиентов с помощью key-value хранилища
- [Программирование, Java] 10 топовых плагинов для IntelliJ IDEA, которые ты не должен пропустить (перевод)
- [Ненормальное программирование, Программирование] Развлечения с парсингом IP-адресов (перевод)
- [Информационная безопасность, Python, Программирование, Машинное обучение] Вышла библиотека PyWhat для автоматического парсинга трафика
- [Python, Программирование, Алгоритмы, Визуализация данных, Учебный процесс в IT] Как я пытался придумать новый подход к изучению алгоритмов через интерактивные визуализации
- [Программирование, Проектирование и рефакторинг, Разработка игр, Unity] Подпишись, чтобы не пропустить — События
- [Программирование, Java] Сравнение Java-записей, Lombok @Data и Kotlin data-классов (перевод)
Теги для поиска: #_programmirovanie (Программирование), #_gejmdev (геймдев), #_shahmaty (шахматы), #_shashki (шашки), #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 27-Апр 02:33
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 7 лет 2 месяца |
|
Добрый вечер хаброжители!Сегодня я предоставлю вашему вниманию небольшую статью не связанную с моими предыдущими статьями. Где-то более года назад мне пришлось делать одно тестовое задание чтобы устроится на работу. Выполнил я его в срок, но конкуренция была большая и скорее всего взяли человека который сделал его с помощью рекомендованных технологий и красочнее.Суть задачи, есть доска 8 на 8 клеток. У игрока есть 9 шашек они расположены в углу доски в квадрате 3 на 3, у противника тоже столько же шашек и они расположены симметрично по диагонали в другом углу в квадрате 3 на 3. Каждый игрок ходит по очереди, нужно дойти шашками на места изначального положения соперника через всю доску, кто первый дошел тот и победил. Ходить можно только на пустые клетки и только вверх, вниз, влево и вправо(по диагонали нельзя!). ![]() Управление я добавил мышью, а играть против компьютерного алгоритма. Черные - человек, белые - ИИ.Помимо всего прочего изначально необходимо отрисовать доску, шашки и делать манипуляции с полем.Немного кода для наглядности: Game::Game()
{ run = true;//флаг признак нажатия кнопки выхода F5 Matrix = new int* [8];//Поле 64 ячейки - значения 0 - для пустой ячейки, для игрока каждая пешка-шашка от 1 до 9, для компьютера значения в матрице от 10 до 18 for (int i = 0; i < 8; i++) Matrix[i] = new int[8]; //Квадраты координат нужны чтобы программа знала какие ячейки над указателем мыши, 64 квадрата QuadCoorXleft = new int* [8];//каждой ячейки матрицы Matrix соответстует квадрат координат для мыши xleft означает левую координату x QuadCoorXright = new int* [8];//xright - правая x QuadCoorYdown = new int* [8];//верхняя y координата QuadCoorYup = new int* [8];//нижняя y координата for (int i = 0; i < 8; i++) { QuadCoorXleft[i] = new int[8]; QuadCoorXright[i] = new int[8]; QuadCoorYdown[i] = new int[8]; QuadCoorYup[i] = new int[8]; } //Координаты пешек для отрисовки ChessX = new double[18];//X ChessY = new double[18];//Y //Выделяемая пешка ее координаты и значения ActiveX = -1;//X ActiveY = -1;//Y Active = -1;//Value firstplayer = true;//флаг того что можете игрок 1й ходить secondplayer = false;//флаг того что можете игрок 2й ходить ai = new bool[18];//ячейки флаги того что пешка на финишной позиции chessai tmp; for (int i = 0; i < 18; i++) { ai[i] = false; if (i > 8) { tmp.ai = ai[i]; tmp.value = i+1; Ai.push_back(tmp);//Вектор с флагами финиша каждой пешки для искуственного интеллекта } } aicountfirstrow = 0;//счетчик кол-ва пешек ИИ(искуственного интеллекта) на верхней строчке(0-я) aicountsecondrow = 0;//счетчик кол-ва пешек ИИ на предверхней строчке(1-я) aicountthirdrow = 0;//счетчик кол-ва пешек ИИ на предпредверхней строчке(2-я) } void Draw_Circle()
{ //Отрисовка круга(пешек-шахмат) черного for (int i = 0; i <= 50; i++) { float a = (float)i / 50.0f * 3.1415f * 2.0f; glVertex2f(cos(a), sin(a)); } } void Draw_Circle_Fill() { //Отрисовка круга(пешек-шахмат) белого for (int i = 0; i <= 50; i++) { float a = (float)i / 50.0f * 3.1415f * 2.0f; glVertex2f(0.0, 0.0); glVertex2f(cos(a), sin(a)); } } ...
for (int i = 0; i < 9; i++) { glPushMatrix(); glTranslatef(ChessX[i], ChessY[i], 0); glScalef(0.05, 0.05, 1); glBegin(GL_LINE_LOOP); Draw_Circle(); glEnd(); glPopMatrix(); } //Рисуем белые пешки ИИ for (int i = 9; i < 18; i++) { glPushMatrix(); glTranslatef(ChessX[i], ChessY[i], 0); glScalef(0.05, 0.05, 1); glBegin(GL_LINES); Draw_Circle_Fill(); glEnd(); glPopMatrix(); } ... void Game::Move_Up()
{ //Ход игрока вверх if (Active > 0 && ActiveX != 0 && Matrix[ActiveX-1][ActiveY] == 0)//Если выделенная пешка и не самая верхняя строчка и ячейка выше пустая { Matrix[ActiveX-1][ActiveY] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке выше текущюю(выделенную пешку) Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую ChessY[Active-1] += 0.2;//перемещаем координату У пешки вверх для отрисовки ActiveX = -1;//стираем координаты выделенной пешки ActiveY = -1;//стираем координаты выделенной пешки Active = -1;//делаем неактивной текущую выделенную фигуру std::cout << " Player MoveUp " << Active << std::endl; firstplayer = false; secondplayer = true;//меняем флаги хода от игрока к ИИ } } void Game::Move_Down() { //Ход игрока вниз if (Active > 0 && ActiveX != 7 && Matrix[ActiveX+1][ActiveY] == 0)//Если выделенная пешка и не самая нижняя строчка и ячейка ниже пустая { Matrix[ActiveX+1][ActiveY] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке ниже текущюю(выделенную пешку) Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую ChessY[Active-1] -= 0.2;//перемещаем координату У пешки вниз для отрисовки ActiveX = -1;//стираем координаты выделенной пешки ActiveY = -1;//стираем координаты выделенной пешки Active = -1;//делаем неактивной текущую выделенную фигуру std::cout << "Player MoveDown " << Active << std::endl; firstplayer = false; secondplayer = true;//меняем флаги хода от игрока к ИИ } } void Game::Move_Right() { //Ход игрока вправо if (Active > 0 && ActiveY != 7 && Matrix[ActiveX][ActiveY+1] == 0)//Если выделенная пешка и не самая правая строчка и ячейка справа пустая { Matrix[ActiveX][ActiveY+1] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке справа текущюю(выделенную пешку) Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую ChessX[Active-1] += 0.2;//перемещаем координату Х пешки вправо для отрисовки ActiveX = -1;//стираем координаты выделенной пешки ActiveY = -1;//стираем координаты выделенной пешки Active = -1;//делаем неактивной текущую выделенную фигуру std::cout << "MoveRight " << Active << std::endl; firstplayer = false; secondplayer = true;//меняем флаги хода от игрока к ИИ } } void Game::Move_Left() { //Ход игрока влево if (Active > 0 && ActiveY != 0 && Matrix[ActiveX][ActiveY-1] == 0)//Если выделенная пешка и не самая левая строчка и ячейка слева пустая { Matrix[ActiveX][ActiveY-1] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке слева текущюю(выделенную пешку) Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую ChessX[Active-1] -= 0.2;//перемещаем координату Х пешки влево для отрисовки ActiveX = -1;//стираем координаты выделенной пешки ActiveY = -1;//стираем координаты выделенной пешки Active = -1;//делаем неактивной текущую выделенную фигуру std::cout << "MoveLeft " << Active << std::endl; firstplayer = false; secondplayer = true;//меняем флаги хода от игрока к ИИ } } void Game::ReccurentWalk()
{ //Реккурентный ход ИИ current = -1, currentI = -1, currentJ = -1;//изначально выделенная пешка не определена for (int i = 0; i < Ai.size(); i++)//поиск по массиву if (!Ai[i].ai)//если не завершены ходы для конкретных пешек { if (Check_MoveUp(Ai[i].value) || Check_MoveLeft(Ai[i].value))//Можно ли походить вверх или влево? { current = Ai[i].value;//запоминаем текущую пешку break; } else { //Если походить нельзя стираем из массива ходов пешку std::vector<chessai>::iterator position = std::find_if(Ai.begin(), Ai.end(), find_s(Ai[i].value)); if (position != Ai.end()) // == vector.end() means the element was not found Ai.erase(position); } } for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) if (Matrix[i][j] == current)//ищем в матрице пешку и запоминаем индексы { currentI = i; currentJ = j; break; } if (currentI != -1 && currentJ != -1)//если какая либо найдена ходим либо вверх либо влево { if (!Move_UpAI(currentI, currentJ)) if (!Move_LeftAI(currentI, currentJ)) { ReccurentWalk(); } } else { //если не найдена заполняем массив ходов снова пешками chessai tmp; for (int i = 0; i < 18; i++) { ai[i] = false; if (i > 8) { tmp.ai = ai[i]; tmp.value = i + 1; Ai.push_back(tmp); } } //ищем ту которая может походить вправо или вниз for (int i = 0; i < Ai.size(); i++) if (!Ai[i].ai) { if (Check_MoveRight(Ai[i].value) || Check_MoveDown(Ai[i].value)) { current = Ai[i].value; break; } else { //если не может то стираем из массива std::vector<chessai>::iterator position = std::find_if(Ai.begin(), Ai.end(), find_s(Ai[i].value)); if (position != Ai.end()) // == Vector.end() means the element was not found Ai.erase(position); } } //ищем ее индексы в матрице for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) if (Matrix[i][j] == current) { currentI = i; currentJ = j; break; } //ходим вправо или вниз if(!Move_RightAI(currentI, currentJ)) if (!Move_DownAI(currentI, currentJ)) { std::cout <<"Artificial Intellegence asked: WTF?" << std::endl; } } chessai tmp; if(Ai.empty())//если список ходов пуст заполняем снова всеми for (int i = 0; i < 18; i++) { ai[i] = false; if (i > 8) { tmp.ai = ai[i]; tmp.value = i + 1; Ai.push_back(tmp); } } } =========== Источник: habr.com =========== Похожие новости:
Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 27-Апр 02:33
Часовой пояс: UTC + 5