Professional Documents
Culture Documents
lr6 Ukr
lr6 Ukr
Звіт
Київ 2021
ЗМІСТ
2 ЗАВДАННЯ...............................................................................................4
3 ВИКОНАННЯ...........................................................................................6
ВИСНОВОК.....................................................................................................7
КРИТЕРІЇ ОЦІНЮВАННЯ..........................................................................8
2
1 МЕТА ЛАБОРАТОРНОЇ РОБОТИ
Мета роботи - вивчити основні підходи до формалізації алгоритмів
знаходження рішень задач в умовах протидії. Ознайомитися з підходами до
програмування алгоритмів штучного інтелекту в іграх з елементами
випадковості та в іграх з неповною інформацією.
3
2 ЗАВДАННЯ
4
12 Ночка http://life-games.net/index/nochka/0-192
13 Табу https://www.durbetsel.ru/2_taboo.htm
14 Чотири рядки https://www.durbetsel.ru/2_chetyre_stroki.htm
15 Свої козирі https://www.durbetsel.ru/2_svoi-koziri.htm
16 Війна з ботами https://www.durbetsel.ru/2_voina_s_botami.htm
17 Вибух https://www.durbetsel.ru/2_vzryv.htm
18 Останній гравець https://www.durbetsel.ru/2_posledny_igrok.htm
19 Скарбнички https://www.durbetsel.ru/2_sunduchki.htm
20 Богач https://www.durbetsel.ru/2_bogach.htm
21 Редуду https://www.durbetsel.ru/2_redudu.htm
22 Эльферн https://www.durbetsel.ru/2_elfern.htm
23 Ремінь https://www.durbetsel.ru/2_remen.htm
24 Курка https://www.durbetsel.ru/2_kurisa.htm
25 Навалка https://www.durbetsel.ru/2_navalka.htm
26 Яцзи https://game-wiki.guru/published/igryi/yaczzyi.html
27 Лудо http://www.iggamecenter.com/info/ru/ludo.html
28 Генерал http://www.rules.net.ru/kost.php?id=7
29 Свиня http://www.rules.net.ru/kost.php?id=3
30 Тринадцять http://www.rules.net.ru/kost.php?id=16
5
3 ВИКОНАННЯ
LUDOBoard board;
Random rand;
public AggressiveLUDOPlayer(LUDOBoard board)
{
this.board = board;
rand = new Random();
}
if(hitOpponentHome(current_board,new_board)) {
return 2+rand.nextFloat();
}
else {
return 1+rand.nextFloat();
}
}
else {
return 0;
}
}
private boolean isSafe(int index) {
return board.isGlobe(index)||
board.almostHome(index,board.getMyColor());
}
private boolean hitOpponentHome(int[][] current_board, int[][]
new_board) {
int opponentsOnField = 0;
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
if(board.getMyColor()!=i) {
if(board.atField(current_board[i][j])&&!
board.atField(new_board[i][j])) {
return true;
}
}
}
}
return false;
}
}
package com.ludo.LUDOSimulator;
/**
* Example of automatic LUDO player
* @author David Johan Christensen
7
*
* @version 0.9
*
*/
public class FifoLUDOPlayer implements LUDOPlayer {
LUDOBoard board;
public FifoLUDOPlayer(LUDOBoard board)
{
this.board = board;
}
public void play() {
board.print("Fifo player playing");
board.rollDice();
for(int i=0;i<4;i++)
{
if(board.moveable(i)) {
board.moveBrick(i);
return;
}
}
}
public synchronized void delay() {
try {
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}package com.ludo.LUDOSimulator;
8
public interface GameEndedListener {
public void gameEnded(int[] result);
}package com.ludo.LUDOSimulator;
import com.minmax.Helpers;
import com.helpers.prprNeuralLUDOPlayer;
import com.helpers.prprTDLUDOPlayer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public LUDO() {
super("LUDO Simulator");
setBackground(Color.white);
board = new LUDOBoard();
add(board, BorderLayout.CENTER);
setResizable(false);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
LUDO.this.dispose();
System.exit(0);
}
});
setVisible(visual);
}
try {
for (int i = 0; i < gameCount; i++) {
board.play();
board.kill();
10
result[0] += board.getPoints()[0];
result[1] += board.getPoints()[1];
result[2] += board.getPoints()[2];
result[3] += board.getPoints()[3];
board.reset();
p.reset(board);
board.setPlayer(p, LUDOBoard.YELLOW);
board.setPlayer(new SemiSmartLUDOPlayer(board),
LUDOBoard.RED);
board.setPlayer(new SemiSmartLUDOPlayer(board),
LUDOBoard.BLUE);
board .setPlayer(new
SemiSmartLUDOPlayer(board),
LUDOBoard.GREEN);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return result[0];
}
try {
for (int i = 0; i < iter; i+=4) {
board.play();
board.kill();
result[0] += board.getPoints()[0];
result[1] += board.getPoints()[1];
result[2] += board.getPoints()[2];
result[3] += board.getPoints()[3];
p.play();
board.reset();
p.reset(board);
board.setPlayer(p, LUDOBoard.YELLOW);
board.setPlayer(new RandomLUDOPlayer(board),
LUDOBoard.RED);
board.setPlayer(new RandomLUDOPlayer(board),
LUDOBoard.BLUE);
board
.setPlayer(new
RandomLUDOPlayer(board),
LUDOBoard.GREEN);
if ((i % 100) == 0 && i != 0) {
System.out.println(result[0]);
result = new int[4];
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
p.Debug();
}
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
/**
* The LUDOBoard class is the core class of the LUDO simulator used in the
couse
* of AI01 - tools of artificial intelligence.
*
* Automatic LUDO players may use this class to roll the dice, move a brick
and
* get information about the states of the game relevant to how the bricks
* should be moved.
*
* @author David Johan Christensen
* @version 0.91
*
*
*/
public class LUDOBoard extends Canvas {
public LUDOBoard() {
reset();
17
if (!LUDO.visual)
return;
setSize(1000, 800);
try {
String pathStart = "src/com/ludo/";
boardImage = ImageIO.read(new File(pathStart +
"ludoboard.jpg"));
redBrickImage1 = ImageIO.read(new File(pathStart +
"redbrick.png"));
redBrickImage2 = ImageIO.read(new File(pathStart +
"redbrick.png"));
redBrickImage3 = ImageIO.read(new File(pathStart +
"redbrick.png"));
redBrickImage4 = ImageIO.read(new File(pathStart +
"redbrick.png"));
18
yellowBrickImage3 = ImageIO.read(new File(pathStart +
"yellowbrick.png"));
yellowBrickImage4 = ImageIO.read(new File(pathStart +
"yellowbrick.png"));
if (!LUDO.visual)
return;
float startXPixel = (float) index2Pixel(fromIndex, color)[0]
20
- (brickSize / 2);
float startYPixel = (float) index2Pixel(fromIndex, color)[1]
- (brickSize / 2);
float endXPixel = (float) index2Pixel(toIndex, color)[0]
- (brickSize / 2);
float endYPixel = (float) index2Pixel(toIndex, color)[1]
- (brickSize / 2);
21
try {
wait((long) waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
26
protected int[] index2Pixel(int index, int color) {
/* Start Squares */
if (index >= 100 && index < 104)
return startSquaresXYPos[color][index - 100];
else if (index >= 200 && index < 204)
return startSquaresXYPos[color][index - 200];
else if (index >= 300 && index < 304)
return startSquaresXYPos[color][index - 300];
else if (index >= 400 && index < 404)
return startSquaresXYPos[color][index - 400];
/* Field Squares */
if (index < 52) {
return fieldSquaresXYPos[index];
}
/* Home Squares */
if (index >= 104 && index < 110)
return homeSquaresXYPos[color][index - 104];
else if (index >= 204 && index < 210)
return homeSquaresXYPos[color][index - 204];
else if (index >= 304 && index < 310)
return homeSquaresXYPos[color][index - 304];
else if (index >= 404 && index < 410)
return homeSquaresXYPos[color][index - 404];
29
animateMove(currentColor, nr, bricks[currentColor]
[nr],
startFieldSquares[currentColor]);
bricks[currentColor][nr] =
startFieldSquares[currentColor];
// Hit opponent home from "my" globe
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (bricks[i][j] == bricks[currentColor]
[nr]
&& i != currentColor) {
animateMove(i, j, bricks[i][j], (i +
1) * 100 + j);
bricks[i][j] = (i + 1) * 100 + j;
}
}
}
brickMoved = true;
turns = 1;
print("Now roll the dice...");
return true;
} else {
print("Unable to move the selected brick...");
return false; // Illigal move
}
} else if (!(index <= endFieldSquares[currentColor] && (index +
dice) > endFieldSquares[currentColor])
&& index < 100) /* Moving on the field */
{
int moveToIndex = (index + dice) % 52;
30
animateMove(currentColor, nr, bricks[currentColor][nr],
moveToIndex);
31
(currentColor + 1) *
100 + nr);
moveToIndex = (currentColor + 1)
* 100 + nr; // I am
// hit
// home
} else if (countBricksOn(moveToIndex)
>= 2) { // there
// are
// at
// least
// two
// bricks
animateMove(currentColor, nr,
moveToIndex,
(currentColor + 1) *
100 + nr);
moveToIndex = (currentColor + 1)
* 100 + nr; // I am
// hit
// home
} else { // I hit him home
animateMove(i, j, bricks[i][j], (i +
1) * 100 + j);
bricks[i][j] = (i + 1) * 100 + j;
}
}
}
}
bricks[currentColor][nr] = moveToIndex;
32
brickMoved = true;
if (dice == 6)
turns = 1;
else
turns = 0;
print("Now roll the dice...");
return true;
} else { /* Moving in(to) the home area */
if (index == ((1 + currentColor) * 100 + 9)) {
print("Unable to move the selected brick...");
return false; // Illigal move already home
}
if (index < 51) { /* still on the field */
animateMove(currentColor, nr, bricks[currentColor]
[nr],
(index + dice) - (1 +
endFieldSquares[currentColor])
+ ((1 + currentColor) * 100
+ 4));
bricks[currentColor][nr] = (index + dice)
- (1 + endFieldSquares[currentColor])
+ ((1 + currentColor) * 100 + 4);
} else {
if ((index + dice) > ((1 + currentColor) * 100 + 9)) {
animateMove(currentColor, nr,
bricks[currentColor][nr], 2
* ((1 + currentColor) * 100 + 9) -
(index + dice));
bricks[currentColor][nr] = 2
33
* ((1 + currentColor) * 100 + 9) -
(index + dice);
} else {
animateMove(currentColor, nr,
bricks[currentColor][nr],
(index + dice));
bricks[currentColor][nr] = (index + dice);
}
}
brickMoved = true;
if (dice == 6) {
turns = 1;
print("Now roll the dice...");
} else {
turns = 0;
print("Next Player...");
}
return true;
}
}
37
graphics.drawImage(redBrickImage1,
index2Pixel(bricks[RED][i],
RED)[0]
- (brickSize / 2),
index2Pixel(bricks[RED][i], RED)[1]
- (brickSize / 2), brickSize, brickSize,
null);
break;
case 2:
graphics.drawImage(redBrickImage2,
index2Pixel(bricks[RED][i],
RED)[0]
- (brickSize / 2),
index2Pixel(bricks[RED][i], RED)[1]
- (brickSize / 2), brickSize, brickSize,
null);
break;
case 3:
graphics.drawImage(redBrickImage3,
index2Pixel(bricks[RED][i],
RED)[0]
- (brickSize / 2),
index2Pixel(bricks[RED][i], RED)[1]
- (brickSize / 2), brickSize, brickSize,
null);
break;
case 4:
graphics.drawImage(redBrickImage4,
index2Pixel(bricks[RED][i],
RED)[0]
38
- (brickSize / 2),
index2Pixel(bricks[RED][i], RED)[1]
- (brickSize / 2), brickSize, brickSize,
null);
break;
}
switch (counter[2][i]) {
case 1:
graphics
.drawImage(blueBrickImage1,
index2Pixel(
bricks[BLUE][i], BLUE)[0]
- (brickSize / 2),
index2Pixel(bricks[BLUE][i],
BLUE)[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
case 2:
graphics
.drawImage(blueBrickImage2,
index2Pixel(
bricks[BLUE][i], BLUE)[0]
- (brickSize / 2),
index2Pixel(bricks[BLUE][i],
BLUE)[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
case 3:
39
graphics
.drawImage(blueBrickImage3,
index2Pixel(
bricks[BLUE][i], BLUE)[0]
- (brickSize / 2),
index2Pixel(bricks[BLUE][i],
BLUE)[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
case 4:
graphics
.drawImage(blueBrickImage4,
index2Pixel(
bricks[BLUE][i], BLUE)[0]
- (brickSize / 2),
index2Pixel(bricks[BLUE][i],
BLUE)[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
}
switch (counter[3][i]) {
case 1:
graphics.drawImage(greenBrickImage1, index2Pixel(
bricks[GREEN][i], GREEN)[0]
- (brickSize / 2),
index2Pixel(bricks[GREEN][i], GREEN)
[1]
40
- (brickSize / 2), brickSize,
brickSize, null);
break;
case 2:
graphics.drawImage(greenBrickImage2, index2Pixel(
bricks[GREEN][i], GREEN)[0]
- (brickSize / 2),
index2Pixel(bricks[GREEN][i], GREEN)
[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
case 3:
graphics.drawImage(greenBrickImage3, index2Pixel(
bricks[GREEN][i], GREEN)[0]
- (brickSize / 2),
index2Pixel(bricks[GREEN][i], GREEN)
[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
case 4:
graphics.drawImage(greenBrickImage4, index2Pixel(
bricks[GREEN][i], GREEN)[0]
- (brickSize / 2),
index2Pixel(bricks[GREEN][i], GREEN)
[1]
- (brickSize / 2), brickSize,
brickSize, null);
break;
41
}
}
}
case YELLOW:
switch (turns) {
case 1:
graphics.drawImage(yellowBrickImage1, x, y, 100,
100, null);
break;
case 2:
graphics.drawImage(yellowBrickImage2, x, y, 100,
100, null);
45
break;
case 3:
graphics.drawImage(yellowBrickImage3, x, y, 100,
100, null);
break;
case 4:
graphics.drawImage(yellowBrickImage4, x, y, 100,
100, null);
break;
}
break;
}
}
int[][] temp = { { 100, 101, 102, 103 }, { 200, 201, 202, 203 },
{ 300, 301, 302, 303 }, { 400, 401, 402, 403 } };
bricks = temp;
int[] temp2 = { 0, 0, 0, 0 };
turnsCounter = temp2;
killed = false;
point = 3;
dice = 0;
repaint();
}
LUDOBoard board;
if(mEvent.getX()>760&&mEvent.getX()<(760+100)&&mEvent.getY()>330&&mEv
ent.getY()<(330+100)) {
board.rollDice();
if(board.nothingToDo()) playing = false;
}
else {
int[] myBricks = board.getMyBricks();
double min = 10000;
int nr = -1;
for(int i=0;i<4;i++) {
int[] xy =
board.index2Pixel(myBricks[i],board.getMyColor());
double temp = (xy[0]-mEvent.getX())*(xy[0]-
mEvent.getX())+(xy[1]-mEvent.getY())*(xy[1]-mEvent.getY());
if(temp<min) {
min= temp;
nr = i;
}
}
if(nr!=-1&&min<250) {
if(board.moveBrick(nr)) playing = false;
else board.print("Unable to move selected brick...");
52
}
else {
board.print("You must click one of your bricks...");
}
}
}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
}package com.ludo.LUDOSimulator;
import java.util.Random;
/**
* Example of automatic LUDO player
* @author David Johan Christensen
*
* @version 0.9
*
*/
public class PacifisticLUDOPlayer implements LUDOPlayer {
LUDOBoard board;
Random rand;
public PacifisticLUDOPlayer(LUDOBoard board)
{
this.board = board;
rand = new Random();
}
if(!hitOpponentHome(current_board,new_board)) {
return 2+rand.nextFloat();
}
else {
return 1+rand.nextFloat();
}
}
else {
54
return 0;
}
}
private boolean hitOpponentHome(int[][] current_board, int[][]
new_board) {
int opponentsOnField = 0;
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
if(board.getMyColor()!=i) {
if(board.atField(current_board[i][j])&&!
board.atField(new_board[i][j])) {
return true;
}
}
}
}
return false;
}
}
package com.ludo.LUDOSimulator;
import java.util.Random;
/**
* Example of automatic LUDO player
* @author David Johan Christensen
*
* @version 0.9
*
*/
public class RandomLUDOPlayer implements LUDOPlayer{
55
LUDOBoard board;
Random rand;
public RandomLUDOPlayer(LUDOBoard board)
{
this.board = board;
rand = new Random();
}
public void play() {
board.print("Random player playing");
board.rollDice();
int nr=-1;
double best = 0;
for(int i=0;i<4;i++) // find a random moveable brick
{
if(board.moveable(i)) {
double temp = rand.nextDouble();
if(temp>best) {
best = temp;
nr = i;
}
}
}
if(nr!=-1) board.moveBrick(nr);
//else nothing to do - no moveable bricks
}
public synchronized void delay() {
try {
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
56
}
}
}package com.ludo.LUDOSimulator;
import java.util.Random;
/**
* Example of automatic LUDO player
* @author David Johan Christensen
*
* @version 0.9
*
*/
public class SemiSmartLUDOPlayer implements LUDOPlayer {
LUDOBoard board;
Random rand;
public SemiSmartLUDOPlayer(LUDOBoard board)
{
this.board = board;
rand = new Random();
}
if(hitOpponentHome(current_board,new_board)) {
return 5+rand.nextFloat();
}
else if(hitMySelfHome(current_board,new_board)) {
return (float)0.1;
}
else if(board.isStar(new_board[board.getMyColor()][i])) {
return 4+rand.nextFloat();
}
else if(moveOut(current_board,new_board)) {
return 3+rand.nextFloat();
}
else if(board.atHome(new_board[board.getMyColor()]
[i],board.getMyColor())) {
return 2+rand.nextFloat();
}
58
else {
return 1+rand.nextFloat();
}
}
else {
return 0;
}
}
import java.util.Random;
mSize = 0;
60
nCount = 0;
return fitnessDifference;
}
if (layer == -1)
return;
64
if (RandomGenerator.generator.nextFloat() <=
MutateProbability) {
mData[i] =
RandomGenerator.generator.nextGaussian();
}
}
}
65
public void setNeuronWeight(int index, double[] weights) {
// double[] weights;
int layer = -1;
for (int i = 1; i < networkConfig.length; i++) {
if (index < networkConfig[i]) {
layer = i;
break;
} else
index -= networkConfig[i];
}
if (layer == -1)
return;
return c;
}
}package com.minmax;
}package com.minmax;
68
import com.ludo.LUDOSimulator.LUDO;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
mGenes.add(children[0]);
mGenes.add(children[1]);
}
70
// Reproduce
if (parent1 != -1 && parent2 != -1) {
Reproduce(parent1, parent2);
}
// Evaluate population
SortPopulation();
float populationFitness = 0;
for (int i = 0; i < mGenes.size(); i++) {
populationFitness += mGenes.get(i).getFitness();
}
/*
* System.out.println("Average Population Fitness = " +
* Float.toString(populationFitness / mGenes.size()));
this.Debug();
*/
return populationFitness / mGenes.size();
}
72
if(!board.inStartArea(current_board[board.getMyColor()]
[i],board.getMyColor())&&board.inStartArea(new_board[board.getMyColor()]
[i],board.getMyColor())) {
return true;
}
}
return false;
}
}
73
Рисунок 3.1 –
Рисунок 3.2 –
3.2
74
ВИСНОВОК
75
КРИТЕРІЇ ОЦІНЮВАННЯ
76