package com.tacoid.pweek.logic; public class IAHard implements IA { float sum = 0f; private GameLogic logic; private int potentiel; private Solution dyn[][]; public IAHard(GameLogic logic) { this.logic = logic; } private class Solution implements Comparable<Solution> { private int potentiel; private int m; private int points; private int h; public Solution(int points, int potentiel, int h, int m) { this.points = points; this.potentiel = potentiel; this.h = h; this.m = m; } @Override public int compareTo(Solution another) { if (points != another.points) { // On choisit ce qui rapporte le plus de points. return points - another.points; } else if (points > 0 || Math.abs(potentiel - 2 * h - (another.potentiel - 2 * another.h)) < 2) { // Si 2 solutions rapportent des points, ou que le potentiel est à peu près identique on prend le plus sûr. return another.m - m; } else { // Si aucun ne rapporte de point et potentiel bien différent, on utilise le potentiel. return potentiel - 2 * h - (another.potentiel - 2 * another.h); } } } private Solution choice(int n, GameLogic cl, int m) { Coord p1 = cl.getPiece().coords[0]; Coord p2 = cl.getPiece().coords[1]; int dl = (int)(p1.l - p2.l); int dc = (int)(p1.c - p2.c); int r; if (dl == 0) { if (dc == 1) { r = 0; } else { r = 1; } } else if (dl == 1) { r = 2; } else { r = 3; } if (dyn[(int)p1.l * GameLogic.COLUMNS + (int)p1.c][r] != null) { // Si on a déjà été dans cette position en moins de mouvement if (dyn[(int)p1.l * GameLogic.COLUMNS + (int)p1.c][r].m <= m) { // Alors c'est naze. return new Solution(-1, 0, 0, 0); } } if (n == 0) { cl.poseEtGravity(); int points = cl.descendreEtPose(); potentiel = 0; cl.gridFF = new boolean[GameLogic.LINES][GameLogic.COLUMNS]; for (int l = 0; l < GameLogic.LINES; l++) { for (int c = 0; c < GameLogic.COLUMNS; c++) { if (cl.grid[l][c] > 0 && cl.grid[l][c] != cl.GARBAGE) { int count = floodfill(l, c, cl.grid[l][c], cl); if (count > 1) { potentiel += count * count; } } } } /* if (cl.getPiece()[0].coul != cl.getPiece()[1].coul) { for (Coord c : cl.getPiece()) { int count = floodfill(c.l, c.c, c.coul, cl); if (count > 2) { diff += -(count - 1) * (count - 1) + count * count; } else if (count == 2) { diff += count * count; } } } else { Coord c = cl.getPiece()[0]; int count = floodfill(c.l, c.c, c.coul, cl); diff = -(count - 2) * (count - 2) + count * count; }*/ int h = hauteur(cl); dyn[(int)p1.l * GameLogic.COLUMNS + (int)p1.c][r] = new Solution(points, potentiel, h, m); return dyn[(int)p1.l * GameLogic.COLUMNS + (int)p1.c][r]; } else { GameLogic[] logics = new GameLogic[5]; logics[0] = new GameLogic(cl,true); logics[1] = new GameLogic(cl,true); logics[1].rotateLeft(); logics[2] = new GameLogic(cl,true); logics[2].rotateRight(); logics[3] = new GameLogic(cl,true); logics[3].moveLeft(); logics[4] = new GameLogic(cl,true); logics[4].moveRight(); Solution scoreMax = choice(0, logics[0], m); int max = 0; for (int i = 1; i < 5; i++) { if (logics[i].getPiece().coords[0].equals(logic.getPiece().coords[0]) && logics[i].getPiece().coords[1].equals(logic.getPiece().coords[1])) { // Si le déplacement ou la rotation a marché, sinon ça sert à rien. continue; } Solution score = choice(n - 1, logics[i], m + 1); if (score.compareTo(scoreMax) > 0) { max = i; scoreMax = score; } } if (n == 4) { switch (max) { case 0: logic.down(); break; case 1: logic.rotateLeft(); break; case 2: logic.rotateRight(); break; case 3: logic.moveLeft(); break; case 4: logic.moveRight(); break; } } dyn[(int)p1.l * GameLogic.COLUMNS + (int)p1.c][r] = scoreMax; return dyn[(int)p1.l * GameLogic.COLUMNS + (int)p1.c][r]; } } private int hauteur(GameLogic logic) { int l = GameLogic.LINES - 1; while (l >= 0) { for (int c = 0; c < GameLogic.COLUMNS; c++) { if (logic.grid[l][c] != 0) { return l + 1; } } l--; } return 0; } private int floodfill(int l, int c, int coul, GameLogic logic) { if (l < 0 || c < 0 || l >= GameLogic.LINES || c >= GameLogic.COLUMNS || logic.grid[l][c] != coul) { return 0; } logic.grid[l][c] = -1; return 1 + floodfill(l + 1, c, coul, logic) + floodfill(l - 1, c, coul, logic) + floodfill(l, c + 1, coul, logic) + floodfill(l, c - 1, coul, logic); } public void choice1() { dyn = new Solution[(GameLogic.LINES + 1) * GameLogic.COLUMNS][4]; choice(4, logic, 0); } public void update(float delta) { if (logic.getState() == State.MOVE && !logic.paused) { sum += delta; if (sum > 0.2) { sum = 0; choice1(); } } } }