Ajedrez extraño como prueba

¡Buenas noches, habitantes nativos!





Hoy llamaré su atención sobre un pequeño artículo que no está relacionado con mis artículos anteriores. Hace más de un año, tuve que hacer una prueba para conseguir un trabajo. Lo completé a tiempo, pero la competencia fue excelente y lo más probable es que contrataran a una persona que lo hizo usando las tecnologías recomendadas y más colorido.





La esencia del problema es que hay un tablero de 8 por 8 celdas. El jugador tiene 9 fichas, están ubicadas en la esquina del tablero en un cuadrado de 3 por 3, el oponente también tiene el mismo número de fichas y están ubicadas simétricamente en diagonal en otra esquina en un cuadrado de 3 por 3. Cada jugador toma turnos, es necesario llegar a la posición original con las damas, el oponente en todo el tablero, quien alcanzó el primero y ganó. Solo puede moverse a celdas vacías y solo hacia arriba, abajo, izquierda y derecha (¡no puede ir en diagonal!).





Agregué controles con un mouse y jugué contra un algoritmo de computadora. Los negros son humanos, los blancos son IA.





Entre otras cosas, inicialmente es necesario dibujar el tablero, las damas y manipular el campo.





Un poco de código para mayor claridad:





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-)
}
      
      



Las bibliotecas OpenGL y SDL2 se utilizan para dibujar y capturar el mouse.





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));
	}
}
      
      



Lo más conveniente es que puedes usar glTranslatef para llenar el tablero de damas con movimientos





...
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();
		}

...
      
      



Movimientos del jugador:





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;//      
	}
}
      
      



Los movimientos de la computadora son casi similares a los movimientos del jugador, al final habrá un enlace al código completo del juego, si alguien está interesado.





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);
			}
		}
}
      
      



Bueno, de hecho, describiré con palabras lo que está haciendo la IA. Recoge tres peones en la parte superior de la línea 0 y, si es imposible moverse hacia la izquierda, sube los 3 peones restantes en 1 línea, de manera similar a la línea 2. Si es imposible moverse hacia la izquierda y hacia arriba, entonces toma cualquier ficha y se mueve hacia abajo o hacia la derecha si es posible, por supuesto, es decir, siempre se esfuerza por moverse hacia la izquierda o hacia arriba (siempre que haya menos de tres fichas en la línea de arriba).





Bueno, en realidad, la jugabilidad:





Y un enlace al código fuente .








All Articles