Русский
Русский
English
Статистика
Реклама

Шашки

Recovery mode Странные шахматы как тестовое задание

17.06.2021 22:13:59 | Автор: admin

Добрый вечер хаброжители!

Сегодня я предоставлю вашему вниманию небольшую статью не связанную с моими предыдущими статьями. Где-то более года назад мне пришлось делать одно тестовое задание чтобы устроится на работу. Выполнил я его в срок, но конкуренция была большая и скорее всего взяли человека который сделал его с помощью рекомендованных технологий и красочнее.

Суть задачи, есть доска 8 на 8 клеток. У игрока есть 9 шашек они расположены в углу доски в квадрате 3 на 3, у противника тоже столько же шашек и они расположены симметрично по диагонали в другом углу в квадрате 3 на 3. Каждый игрок ходит по очереди, нужно дойти шашками на места изначального положения соперника через всю доску, кто первый дошел тот и победил. Ходить можно только на пустые клетки и только вверх, вниз, влево и вправо(по диагонали нельзя!).

Управление я добавил мышью, а играть против компьютерного алгоритма. Черные - человек, белые - ИИ.

Помимо всего прочего изначально необходимо отрисовать доску, шашки и делать манипуляции с полем.

Немного кода для наглядности:

Game::Game(){run = true;//флаг признак нажатия кнопки выхода F5Matrix = new int* [8];//Поле 64 ячейки - значения 0 - для пустой ячейки, для игрока каждая пешка-шашка от 1 до 9, для компьютера значения в матрице от 10 до 18for (int i = 0; i < 8; i++)Matrix[i] = new int[8];//Квадраты координат нужны чтобы программа знала какие ячейки над указателем мыши, 64 квадратаQuadCoorXleft = new int* [8];//каждой ячейки матрицы Matrix соответстует квадрат координат для мыши xleft означает левую координату xQuadCoorXright = new int* [8];//xright - правая xQuadCoorYdown = 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];//XChessY = new double[18];//Y//Выделяемая пешка ее координаты и значенияActiveX = -1;//XActiveY = -1;//YActive = -1;//Valuefirstplayer = 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 foundAi.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 foundAi.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-ю строку. Если ходить влево и вверх нельзя, то он берет любую шашку и двигает либо вниз либо вправо если можно конечно, то есть стремится всегда двигать влево или вверх( при условии что выше меньше двух шашек в строке).

Ну собственно и геймплей:

https://youtu.be/XaQVeSKdQcs

И ссылка на исходный код:

https://github.com/Beginerok/DominiGames

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru