ITI0011-2014:Gomoku

Allikas: Kursused
Redaktsioon seisuga 25. november 2014, kell 10:38 kasutajalt Ago (arutelu | kaastöö) (→‎Rakendus)
Mine navigeerimisribale Mine otsikasti


Work in progress, vaadake jooksvalt uut seisu!

Rakendus

Versioon 0.3 GUI-st: Meedia:Gomoku_v0.3.zip (seisuga 25. nov 12:00)

Uuendused:

0.3:

  • 2013. aasta turniiri võitja (OpponentWinner)

0.2:

  • Lisatud vastased OpponentWeak ja OpponentStrong
  • Nimetatud vastased pole veel lõplikud. Küll võib arvestada, et 10p saamiseks peate vähemalt OpponentWeak'ist jagu saama. Võib juhtuda, et OpponentWeak ise muutub natuke lihtsamaks.

Versioon kindlasti uueneb!

Käivitamine Eclipse'is

Zip-fail tuleb lahti pakkida näiteks workspace'i sisse (tekib workspace'i alla gomoku kaust). Nüüd eclipse'is file -> import -> General->Existing projects into Workspace -> nüüd valite kausta kettal ja finish. Peaks tekkima projekt nimega "gomoku".

Alternatiivne käivitamine

Kui eelmine meetod ei tööta, siis tuleb failid käsitsi kopeerida:

  • Tõmba alla zip-fail
  • tee Eclipse'is uus Java projekt
  • kopeeri kõik zip-failis "gomoku/src" kaustas olevad failid loodud projekti "src" kausta (loodud projekti asukoha leiad näiteks projekti peal parem klikk - properties -> Resource, seal on "Location", mis näitab asukohta kettal).
  • paki zip-failis olev "lib/strat_impl.jar" fail kuskile kettale lahti. Näiteks projekti alla loo uus kaust "lib" ja kopeeri sinna.
  • projekti peal parem klikk - properties -> Java Build Path -> Libraries -> "Add External JARs" nupp (kui panid projekti alla, siis võta "Add JARs...")
  • otsi avanevas dialoogis strat_impl.jar fail üles ja "OK" või "Open"

Nüüd peaks Main.java failist projekt käivitatav olema.

Andke teada, kui projekti importimine ei õnnestu.

Mõned näpunäited teiste tudengite probleemidest

Tänan kõiki, kes on saatnud infot, kuidas nad on saanud projekti endal käima!



IntelliJ IDE-l tundub olevat probleem meetodiga

     initializeGameStatusListener() 

Sest seal kasutuses lambda (täpne error siis):

     Lambda expressions are not supported at this language level.

Stacki juhendamisel läksin siis

     File -> Project Structure (Ctrl+Alt+Shift+S)

ning "Project" tabi alt sai muuta Language Levelit. IntelliJ-l on see vaikimisi 6 peal kuid lambdade jaoks peab 8-ks muutma nähtavasti.



Kui tekib JavaFX-iga viga, mis ütleb midagi keelatud klasside kohta, võib abi olla sellest: http://stackoverflow.com/questions/9266632/access-restriction-is-not-accessible-due-to-restriction-on-required-library#answer-9586411


Kui sul on tekkinud mõni probleem ja oled selle ära lahendanud, palun saada email: ago.luberg @ ttu.ee . Saan siis selle ka siia lisada.

TODO

  • lisada vastased, kellest peate punktide saamiseks jagu saama. (peaaegu tehtud :) )
  • lisada ajapiirangu kontroll
  • 20x20 laud

Lisapunktid

Kes leiab mõne vea ja selle jaoks ka koodiparanduse antud rakenduses, võib teenida lisapunkte. Ka on oodatud kõiksugu ettepanekud parendamise osas (kasutajamugavus, väljanägemine, töökindlstu, turvalisus jms).

Ülesande lühikirjeldus

Peate kirjutama StudentStrategy.getMove() sisu selliselt, et see mängiks piisavalt hästi. Võite sinna faili teha uusi meetodeid. Väliste librarite ja täiendavate klasside kasutamine ei ole lubatud! Ehk siis kogu koodi peate sellesse faili panema.

Aja jooksul tekib siia lehele erineva tugevusega vastased, kellest peate jagu saama. Vastaseid on 3: kõige nõrgema alistamine annab 5p, keskmise alistamine annab 8p, kõige tugevama vastase alistamine annab 10p. Ülesannet võib teha üksi või kahekesi. Kahekesi tegemise eeldus on see, et mõlemad tudengid saavad igast koodireast aru. 8p või 10p puhul peaks kasutama minimax (või alpha-beta kärpimist) algoritmi. 5p saamiseks piisab ka mingist muust lahendusest.

Vastase alistamise tingimus on see, et mängitakse 10 mängu. Vähemalt 6 mängu peaks võitma teie strateegia. Käigu tegemiseks on mõlemal mängijal aga kuni 1 sekund (hetkel ranget kontrolli selleks pole, aga võib hilisemas versioonis tulla).

Kaitsma tulles peab strateegia töötama viimase versiooniga antud rakendusest. Üldiselt midagi olulist teie jaoks ei muutu. Üks konkreetne näide, mis võib muutuda, on ajapiirang. Hetkel ajapiirangut rakenduses pole. Aga võib juhtuda, et kui teie käiguarvutus kulutab üles 1 sekundi aega, lõpetatakse see protsess ja tehakse suvaline käik.

Android

Androidi versioon sellest ülesandest on selline, et kõik siinsed nõuded jäävad samaks, aga te peate GUI osa ise realiseerima Androidi peale. Aga ComputerStrategy interface, Location ja SimpleBoard objektid peaksid samaks jääma, et saaks kasutada samu vastaseid teie strateegia tugevuse mõõtmiseks.

Androidile tegemise puhul saate +5p selle eest, et GUI ja loogika töötab Androidi peal. Aluseks saate võtta JavaFX-i GUI ja loogika. Ehk siis kõige nõrgema vastase võitmisel saate 10p, keskmise võitmisel 13p, tugevaima võitmisel 15p.

Mida teha

Tuleb implementeerida interface'i: <source lang="java"> package gomoku;

/**

* @author Ago
*
* Interface for computer strategy.
*/

public interface ComputerStrategy { /** * Takes the game state and return the best move * @param board Board state * @param player Player indicator. Which player's * strategy it is. Possible values: SimpleBoard.PLAYER_*. * @return A location where to make computer's move. * * @see SimpleBoard * @see Location */ public Location getMove(SimpleBoard board, int player);

/** * Name will be shown during the play. * This method should be overridden to * show student's name. * @return Name of the player */ public String getName(); } </source>

Objekt, mis antakse "getMove" meetodile kaasa:

<source lang="java"> package gomoku;

/**

* Simple 2-dimensional presentation
* of the game board.
* Every cell in the board is represented
* by one integer, the Values are either
* PLAYER_BLACK, PLAYER_WHITE or EMPTY.
* This object also knows the size of the board
* and the last move (Location object).
* 
* @author Ago
* @see Location
*/

public class SimpleBoard {

/** * Cell value for black player's piece */ public static final int PLAYER_BLACK = 1;

/** * Cell value for white player's piece */ public static final int PLAYER_WHITE = -1;

/** * Empty cell value */ public static final int EMPTY = 0;

/** * The height of the board. * Indicates the number of rows. */ private int height = -1; /** * The width of the board. * Indicates the number of columns. */ private int width = -1;

private int[][] board;

/** * Returns the height (number of rows) * of the board. * @return Number of rows */ public int getHeight() { return height; }

/** * Returns the width (number of columns) * of the board. * @return Number of columns */ public int getWidth() { return width; }

/** * Returns 2-dimensional * array of integers with values * PLAYER_WHITE, PLAYER_BLACK or EMPTY. * The values correspond to * White player's piece, * Black player's piece, * or an empty cell accordingly. * @return */ public int[][] getBoard() { return board; }

/** * Constructor to instantiate the board. * @param simpleBoard 2-dimensional * array for the board. */ public SimpleBoard(int[][] simpleBoard) { height = simpleBoard.length; if (height > 0) width = simpleBoard[0].length; board = simpleBoard; } }

</source>

Teil tuleb "getMove" meetodis tagastada käigu asukoht Location objektina:

<source lang="java"> package gomoku;

/**

* @author Ago
* Location on the board, 0-based.
*/

public class Location { /** * Index of the row. */ private final int row; /** * Index of the column. */ private final int column;

public Location(int row, int column) { this.row = row; this.column = column; }

/** * @return Row index */ public int getRow() { return row; }

/** * @return Column index */ public int getColumn() { return column; }

@Override public String toString() { return String.format("(%d, %d)", row, column); } } </source>

Näidis random strateegia: <source lang="java"> /**

* A random strategy implementation
* for the gomoku game.
* @author Ago
*
*/

public class RandomStrategy implements ComputerStrategy {

@Override public Location getMove(SimpleBoard board, int player) { int[][] b = board.getBoard(); while (true) { // let's loop until we find an empty spot int row = (int)(Math.random() * board.getHeight()); int col = (int)(Math.random() * board.getWidth()); if (b[row][col] == SimpleBoard.EMPTY) { // if empty, let's return this location return new Location(row, col); } } }

@Override public String getName() { return "Random computer strategy"; }

} </source>

Tudeng peab täiendama järgmist klassi: StudentStrategy.java: <source lang="java"> package gomoku;

public class StudentStrategy implements ComputerStrategy {

@Override public Location getMove(SimpleBoard board, int player) { // let's operate on 2-d array int[][] b = board.getBoard(); for (int row = b.length - 1; row >= 0; row--) { for (int col = b[0].length - 1; col >= 0; col--) { if (b[row][col] == SimpleBoard.EMPTY) { // first empty location return new Location(row, col); } } } return null; }

@Override public String getName() { return "Tudengi nimi"; }

}

</source>

Praegune tudengi kood hakkab alt paremalt järjest nuppe mööda rida käima (kui on vaba koht).