⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 backgammonboard.java

📁 人工智能_bachgammonagent
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//package bkgm;
import java.util.*;
import java.io.*;
import java.math.*;

public class BackgammonBoard implements Cloneable {
    // Each cell in our model is free, or has a checker from player 0 or
    // has a checker from player 1
    // (represented respectively by 0, negative, positive)

    // Player 0 is negative counts and moves in negative direction of board index.
    // Player 1 is opposite.
    int[] board;

    // Checkers on bar (that have been hit).  on_bar[0] is first player, on_bar[1] is second player.
    int[] on_bar;
    // Checkers in home.  in_home[0] is first player, in_home[1] is second player.
    int[] in_home;

    // The current dice rolls.
    int dc1;
    int dc2;

    // Print lots 'o stuff or not.
    boolean verbose;

    // Where to print the output
    PrintStream out_stream;

    public static int CHECKERS_PER_PLAYER = 15;
    public static int NUM_POINTS = 24;
    public static int BAR_LOC0 = NUM_POINTS;
    public static int BAR_LOC1 = -1;
    // Set use_doubles to false if you would like to turn off the quadruple moves for testing.
    public static boolean use_doubles = false;
    protected Object clone() {
        BackgammonBoard b = null;
        try {
            b = (BackgammonBoard) super.clone();
        } catch (CloneNotSupportedException e) {
            System.err.println("I caught the error of board cloning");
        }
        b.board = (int[])board.clone();
        b.on_bar = (int[])on_bar.clone();
        b.in_home = (int[])in_home.clone();
        return b;
    }

    public BackgammonBoard(PrintStream ps) {
	out_stream = ps;
	initialize();
    }

    public BackgammonBoard() {
	out_stream = System.out;
        initialize();
    }

    private void initialize() {
        // Allocating space for the array cells
        board = new int[NUM_POINTS];
        on_bar = new int[2];
        in_home = new int[2];

        verbose = true;

        // Initializing the cells to the "free" state (i.e. ZERO)
        for (int i = 0; i < NUM_POINTS; i = i + 1)
            board[i] = 0;

/*
        // Initilizing the checkers for player 0
        board[5]  = -5;
        board[7]  = -3;
        board[12] = -5;
        board[23] = -2;

        // Initilizing the checkers for player 1
        board[0]  = 2;
        board[11] = 5;
        board[16] = 3;
        board[18] = 5;

        on_bar[0] = 0;
        on_bar[1] = 0;
        in_home[0] = 0;
        in_home[1] = 0;
*/
        
        // Initilizing the checkers for player
		board[5]  = 0;
        board[7]  = 0;
        board[12] = 0;
        board[23] = -2;

        // Initilizing the checkers for player 1
        board[0]  = 2;
        board[11] = 0;
        board[16] = 0;
        board[18] = 0;

        on_bar[0] = 0;
        on_bar[1] = 0;
        in_home[0] = 0;
        in_home[1] = 0;

    }

    // Apply Move m for player to the board.
    public void applyMove(int player, Move m)
    {
	if (m != null) {
	    if (player==0)
		m.sortDescend();
	    else
		m.sortAscend();

	    Iterator iter = m.getAtomicMoves();

	    try {
		while (iter.hasNext()) {
		    AtomicMove am = (AtomicMove) iter.next();
		    if (verbose) {
			out_stream.println("Agent"+ player +" selects move:  (" + am.source_column + "," + am.dest_column + ") (source, dest)");
		    }
		    applyAtomicMove(player,am);
		}
	    } catch (NoSuchElementException e) {
		System.err.println("Error in applying move for player " + player);
	    }
	}
    }

    private void applyAtomicMove(int player, AtomicMove am) {
        pickChecker(player, am.source_column);
        putChecker(player, am.dest_column);
    }

    // Remove a checker from a location.
    private void pickChecker(int player, int column) {
        if ((column < -1) || (column > NUM_POINTS)) {
            System.err.println("Error, out of range.");
        } else {
            // column -1 means the table!
            // So if a checker is transfered from the column -1, it is simply put in the game.
            if (column == BAR_LOC1 || column == BAR_LOC0) {
                if (on_bar[player] < 1)
                    System.err.println("Error, no pieces on bar.");
                else
                    on_bar[player]--;
            } else {
                int p_type = pType(player);
                if (((p_type) * board[column]) >= p_type) {
                    board[column] -= p_type; 
                } else {
                    System.err.println("Error, no pieces at this location.");
                }
            }
        }

    }

    // Wrapper to get count type (-1/+1) from player number (0/1)
    public int pType(int player) {
        return player==0 ? -1 : 1;
    }


    // Place one of player's checkers at location column.
    // Handles hitting of blots, prints error if this is an invalid move (should never happen).
    private void putChecker(int player, int column) {
        if ((column < -1) || (column > NUM_POINTS)) {
            System.err.println("Error, out of range.");
        } else {
            int p_type = pType(player);
            if (column==-1 || column==NUM_POINTS) {
                in_home[player]++;
            } else if (p_type * board[column] >= 0) {
                board[column] += p_type;
            } else if (board[column] == -p_type) {
                board[column] = p_type;
                on_bar[((player+1) % 2)]++;
            } else {
                System.err.println("Error, too many opponent pieces at this locations.");
            }
        }

    }

    // Get a set of valid moves for a player, assuming it's his/her
    // turn, given the current dice roll.
    public MoveSet getValidMoves(int player) {
        Move empty_move = new Move();
	    MoveSet rtn_mset = null;
        int[] dice;
        int dice_left;
        if ((dc1==dc2)&&(use_doubles)) {
            dice_left = 4;
            dice = new int[4];
            dice[0]=dc1;
            dice[1]=dc1;
            dice[2]=dc1;
            dice[3]=dc1;


	    int s_pos = player==1 ? 0 : NUM_POINTS-1;
	    rtn_mset = getValidMovesDoublesRec(empty_move, player, dice_left, dice, s_pos);
	    // Doubles version does not guarrantee maximum number of dice is used.
	    if (rtn_mset != null)
		rtn_mset.maxify();
        } else {
            dice_left = 2;
            dice = new int[2];

	    // Make two calls to getValidMovesRec, one for each ordering of the dice.
	    // Remove duplicate moves later.
	    dice[0]=dc1;
	    dice[1]=dc2;
	    rtn_mset = getValidMovesRec(empty_move, player, dice_left, dice);

	    dice[0]=dc2;
	    dice[1]=dc1;
	    rtn_mset.addSet(getValidMovesRec(empty_move, player, dice_left, dice));

	    if (rtn_mset != null) {
		// Must use as many dice as possible.
		rtn_mset.maxify();
		// If you can only move one die, the larger must be used.
		rtn_mset.bigify(dc1,dc2);
	    }
        }
	// Remove duplicate moves from MoveSet.
	if (rtn_mset != null) {
	    rtn_mset.uniquify();

	    // Moves must be in descending order for player 0, ascending order for player 1.
	    for (Iterator iter = rtn_mset.getIterator(); iter.hasNext(); ) {
		if (player==0)
		    ((Move) iter.next()).sortDescend();
		else
		    ((Move) iter.next()).sortAscend();
	    }
	}
	return rtn_mset;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -