ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Javaの課題丸投げコミュのゲームプログラムの改良

  • mixiチェック
  • このエントリーをはてなブックマークに追加


与えられたオセロのプログラム(実行できるもの)
があるのですが今の段階ではおけるところから
ランダムに石を置くようになっていますが
強いプログラムにしたいのですがどうしたら
よいでしょうか><?


ファイルも多く
長いのですが目を通して頂けると嬉しいです。



public class Main {
public static void main(String[] args) {
Othello othello = new Othello();
OthelloGui othelloGui = new OthelloGui(othello);
othello.addOthelloObserver(othelloGui);
Player p0 = new HumanPlayer(othelloGui,PieceColor.BLACK,"先手");
// Player p0 = new RandomPlayer(PieceColor.BLACK,"先手");
Player p1 = new RandomPlayer(PieceColor.WHITE,"後手");
othello.setTurnInterval(50);
othello.play(p0, p1);
}
}


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Othello {
private Board board = new Board();
private Player[] players = new Player[2]; // 0: black, 1: white
private int turnCount;
private boolean isMoved;
private Player currentPlayer;
private long turnInterval;
public void setTurnInterval(long msec) {
this.turnInterval = msec;
}
public void play(Player p1, Player p2) {
players[0] = p1;
players[1] = p2;
board.initBoard();
currentPlayer = p1;
turnCount = 0;
gameStart();
while (!board.isGameOver()) {
currentPlayer = players[turnCount % players.length];
turnStart();
if (board.canPlace(currentPlayer.getColor())) {
Position pos = currentPlayer.nextMove(board);
board.placeAt(pos.getX(), pos.getY(), currentPlayer.getColor());
isMoved = true;
} else {
isMoved = false; // passed
}
turnEnd();
turnCount++;
sleep(turnInterval);
}
gameEnd();
}
public Board getBoard() {
return board;
}
public Player getCurrentPlayer() {
return currentPlayer;
}
public Player getPlayer1() {
return players[0];
}
public Player getPlayer2() {
return players[1];
}
public boolean isMoved() {
return isMoved;
}
public boolean isPassed() {
return !isMoved;
}
public Player getWinner() {
int c0 = getPieceCount(players[0]);
int c1 = getPieceCount(players[1]);
if (c0 > c1) {
return players[0];
} else if (c0 < c1) {
return players[1];
} else {
return null;
}
}
public int getPieceCount(Player player) {
return board.getPieceCount(player.getColor());
}
private void sleep(long msec) {
try {
Thread.sleep(msec);
} catch (InterruptedException e) {
}
}
private List<OthelloObserver> observers = new ArrayList<OthelloObserver>();
public void addOthelloObserver(OthelloObserver o) {
observers.add(o);
}
private void gameStart() {
for (Iterator<OthelloObserver> it = observers.iterator(); it.hasNext(); ) {
it.next().gameStarted(this);
}
}
private void gameEnd() {
for (Iterator<OthelloObserver> it = observers.iterator(); it.hasNext(); ) {
it.next().gameEnded(this);
}
}
private void turnStart() {
for (Iterator<OthelloObserver> it = observers.iterator(); it.hasNext(); ) {
it.next().turnStarted(this);
}
}
private void turnEnd() {
for (Iterator<OthelloObserver> it = observers.iterator(); it.hasNext(); ) {
it.next().turnEnded(this);
}
}
}



public abstract class BasicPlayer implements Player {
private int color;
private String name;
public BasicPlayer(int color) {
this(color,"Player");
}
public BasicPlayer(int color, String name) {
this.color = color;
this.name = name;
}
public String getName() {
return name;
}
public int getColor() {
return color;
}
@Override
public String toString() {
String c = PieceColor.toColorString(color);
return name+"("+c+")";
}
public abstract Position nextMove(Board board);
}



import java.awt.Font;

import javax.swing.JLabel;

class BigLabel extends JLabel {
public BigLabel(String text) {
super(text);
setHorizontalAlignment(CENTER);
}
public void setFontSize(float size) {
Font font = getFont();
Font bigFont = font.deriveFont(size);
setFont(bigFont);
}
}



public class Board {
private int width = 8;
private int height = 8;
/*
* boardの各要素の値は
* EMPTY,BLACK,WHITE
* のいずれか。
*/
private int[][] board;
public Board() {
board = new int[width][height];
initBoard();
}
public void initBoard() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
board[x][y] = PieceColor.EMPTY;
}
}
int cx = width / 2 - 1;
int cy = height / 2 - 1;
board[cx][cy] = PieceColor.WHITE;
board[cx + 1][cy] = PieceColor.BLACK;
board[cx][cy + 1] = PieceColor.BLACK;
board[cx + 1][cy + 1] = PieceColor.WHITE;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public int getPieceColor(int x, int y) {
return board[x][y];
}
private boolean isOnBoard(int x, int y) {
return isOnBoardX(x) && isOnBoardY(y);
}
private boolean isOnBoardX(int x) {
return 0 <= x && x < width;
}
private boolean isOnBoardY(int y) {
return 0 <= y && y < height;
}
public boolean isGameOver() {
return !canPlace(PieceColor.BLACK) && !canPlace(PieceColor.WHITE);
}
public int getPieceCount(int color) {
int count = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (board[x][y] == color) {
count++;
}
}
}
return count;
}
public void placeAt(int x, int y,int myColor) {
if (canPlaceAt(x, y, myColor)) {
board[x][y] = myColor;
reverse(x, y, myColor);
}
}
public boolean canPlace(int myColor) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if(canPlaceAt(x,y,myColor)) {
return true;
}
}
}
return false;

}
public boolean canPlaceAt(int x, int y,int myColor) {
// return isOnBoard(x, y) && board[x][y] == PieceColor.EMPTY;
if (x >= width || y >= width) {
return false;
}
if (board[x][y] != PieceColor.EMPTY) {
return false;
}
if (canPlaceAt(x, y, -1, 1, myColor)) {
return true;
}
if (canPlaceAt(x, y, 1, -1, myColor)) {
return true;
}
if (canPlaceAt(x, y, -1,-1, myColor)) {
return true;
}
if (canPlaceAt(x, y, 1, 1, myColor)) {
return true;
}
if (canPlaceAt(x, y, 0,-1, myColor)) {
return true;
}
if (canPlaceAt(x, y, -1, 0, myColor)) {
return true;
}
if (canPlaceAt(x, y, 0, 1, myColor)) {
return true;
}
if (canPlaceAt(x, y, 1, 0, myColor)) {
return true;
}
return false;
}
public boolean canPlaceAt(int x, int y, int s, int t, int myColor) {
x += s;
y += t;

if(x < 0 || x >= width || y < 0 || y >= width) {
return false;
}
if(board[x][y] == myColor) {
return false;
}
if (board[x][y] == PieceColor.EMPTY) {
return false;
}
x += s;
y += t;
while (x >= 0 && x < width && y >= 0 && y < width) {
if (board[x][y] == PieceColor.EMPTY) {
return false;
}
if (board[x][y] == myColor) {
return true;
}
x += s;
y += t;
}
return false;
}
public void reverse(int x, int y, int myColor) {
if (canPlaceAt(x, y, -1, 1, myColor)) {
reverse(x, y, -1, 1, myColor);
}
if (canPlaceAt(x, y, 1, -1, myColor)) {
reverse(x, y, 1, -1, myColor);
}
if (canPlaceAt(x, y, -1,-1, myColor)) {
reverse(x, y, -1,-1, myColor);
}
if (canPlaceAt(x, y, 1, 1, myColor)) {
reverse(x, y, 1, 1, myColor);
}
if (canPlaceAt(x, y, 0,-1, myColor)) {
reverse(x, y, 0,-1, myColor);
}
if (canPlaceAt(x, y, -1, 0, myColor)) {
reverse(x, y, -1, 0, myColor);
}
if (canPlaceAt(x, y, 0, 1, myColor)) {
reverse(x, y, 0, 1, myColor);
}
if (canPlaceAt(x, y, 1, 0, myColor)) {
reverse(x, y, 1, 0, myColor);
}
}
public void reverse(int x, int y, int s, int t, int myColor) {
x += s;
y += t;
while (board[x][y] != myColor) {
board[x][y] = myColor;
x += s;
y += t;
}
}
}


import java.awt.GridLayout;

import javax.swing.JComponent;

public class BoardView extends JComponent {
public BoardView(Othello othello, OthelloGui othelloGui) {
Board board = othello.getBoard();
setLayout(new GridLayout(board.getHeight(),board.getWidth()));
for (int y = 0; y < board.getHeight(); y++) {
for (int x = 0; x < board.getWidth(); x++) {
add(new CellView(x, y, othello, othelloGui));
}
}
}

}


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;

import javax.swing.JComponent;

public class CellView extends JComponent implements MouseListener {
private int x;
private int y;
private Othello othello;
private boolean isMouseOn;
private OthelloGui othelloGui;
public CellView(int x, int y, Othello othello, OthelloGui othelloGui) {
this.x = x;
this.y = y;
this.othello = othello;
this.othelloGui = othelloGui;
addMouseListener(this);
setPreferredSize(new Dimension(50,50));
}
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
int margin = 5;
Shape shape = new Ellipse2D.Double(margin,margin,getWidth()-margin*2,getHeight()-margin*2);
Board board = othello.getBoard();
int color = board.getPieceColor(x, y);
if (color == PieceColor.BLACK) {
g2.setColor(Color.black);
g2.fill(shape);
} else if (color == PieceColor.WHITE) {
g2.setColor(Color.white);
g2.fill(shape);
g2.setColor(Color.gray);
g2.draw(shape);
}
if (isMouseOn) {
g2.setColor(Color.red);
} else {
g2.setColor(Color.gray);
}
g2.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
}
public void mouseClicked(MouseEvent e) {
othelloGui.userClicked(x, y);
}
public void mouseEntered(MouseEvent e) {
isMouseOn = true;
repaint();
}
public void mouseExited(MouseEvent e) {
isMouseOn = false;
repaint();
}
public void mousePressed(MouseEvent e) {
// do nothing
}
public void mouseReleased(MouseEvent e) {
// do nothing
}
}



public class HumanPlayer extends BasicPlayer {
private UserIO othelloUI;
public HumanPlayer(UserIO othelloUI,int color) {
this(othelloUI,color,"Human Player");
}
public HumanPlayer(UserIO othelloUI, int color, String name) {
super(color,name);
this.othelloUI = othelloUI;
}
public Position nextMove(Board board) {
while (true) {
Position p = othelloUI.readPlacePosition();
if (board.canPlaceAt(p.getX(), p.getY(), getColor())) {
return p;
} else {
othelloUI.showMessage("そこは置けません。\n");
}
}
}
}


import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class OthelloGui extends JFrame implements UserIO, OthelloObserver {
private BoardView boardView;
private BigLabel turnLabel;
public OthelloGui(Othello othello) {
super("Othello");
setDefaultCloseOperation(EXIT_ON_CLOSE);
boardView = new BoardView(othello,this);
add(boardView, BorderLayout.CENTER);
turnLabel = new BigLabel("先手(黒)の番");
turnLabel.setFontSize(20.0f);
add(turnLabel,BorderLayout.NORTH);
pack();
setVisible(true);
}
private Position clickPosition;
public void userClicked(int x, int y) {
clickPosition = new Position(x,y);
}
public Position readPlacePosition() {
// マルチスレッドをまだ勉強していないので、仕方がないからbusy wait
clickPosition = null;
while (clickPosition == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
return clickPosition;
}
public void showMessage(String message) {
JOptionPane.showMessageDialog(this, message);
}
public void gameStarted(Othello othello) {
repaint();
}
public void gameEnded(Othello othello) {
repaint();
Player p1 = othello.getPlayer1();
String s1 = othello.getPieceCount(p1)+"個";
Player p2 = othello.getPlayer2();
String s2 = othello.getPieceCount(p2)+"個";

String result = "引き分け";
Player p = othello.getWinner();
if (p != null) {
result = p+"の勝ち";
}

showMessage(result+" "+s1+" : "+s2);
}
public void turnStarted(Othello othello) {
Player p = othello.getCurrentPlayer();
turnLabel.setText(p+"の番");
repaint();
}
public void turnEnded(Othello othello) {
if (othello.isPassed()) {
Player p = othello.getCurrentPlayer();
showMessage(p+" パス");
}
repaint();
}
}


public interface OthelloObserver {
void gameStarted(Othello othello);
void gameEnded(Othello othello);
void turnStarted(Othello othello);
void turnEnded(Othello othello);
}


public class PieceColor {
/*
* これらの定数は、以下の2箇所で使う
* (1) ボードのマスの状態 : EMPTY,BLACK,WHITE
* (2) プレイヤーの色またはコマの色 : BLACK,WHITE (この場合EMPTYはない)
*
* 注)
* enumを使いたいところだが、まだやっていないのでstatic final定数で実現。
*
* クラス名はColorにしたかったが、packageをうまく使えない場合、
* java.awt.Colorと混乱する恐れがあるので、少し長いけどPieceColorにした。
*
* PieceColor.BLACKは長いので、単純名のBLACKを使いたい場合、
* static importを行う
* interfaceにしてimplementsする
* などの解決策がある。
* しかし、まだやっていないので、長いけどPieceColor.BLACKと書く。
*/
public static final int EMPTY = 0;
public static final int BLACK = 1;
public static final int WHITE = 2;
public static int getOpponent(int myColor) {
if (myColor == BLACK) {
return WHITE;
} else {
return BLACK;
}
}
public static String toColorString(int color) {
if (color == BLACK) {
return "黒";
} else if (color == WHITE) {
return "白";
} else {
return "";
}
}
}



public interface Player {
String getName();
int getColor();
Position nextMove(Board board);
}



public class Position {
private int x;
private int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public String toString() {
return "("+x+","+y+")";
}

}



import java.util.Random;

public class RandomPlayer extends BasicPlayer {
public RandomPlayer(int color) {
this(color,"Computer Player");
}
public RandomPlayer(int color, String name) {
super(color,name);
}
private Random random = new Random();
public Position nextMove(Board board) {
int x, y;
do {
x = random.nextInt(board.getWidth());
y = random.nextInt(board.getHeight());
} while (!board.canPlaceAt(x, y, getColor()));
return new Position(x, y);
}
}


public interface UserIO {
Position readPlacePosition();
void showMessage(String message);
}


よろしくお願いいたします。

コメント(6)

各マスに評価値つけて、高いところを選ばせるようにしたら地味に強くなりますよ、たぶん。
実装も簡単ですしね。

あとはなんでしょうね。
「オセロ AI」とか調べたらなんかでてきそうです。

>>いしかわさん

コメントありがとうございます!
参考になりました!!

AIですか!
今までjavaだとかプログラミングで
検索していたのですが試したいと思います!!


>>こださん

ご丁寧にありがとうございます!!電球

1つめのコメントは理解するのが難しいな...と思っていたのですが
再度コメント下さった考え方は私も各マスの優先順位を決めて
優先度の高いところに置けるようにしたいと思っていたので
本当に参考になりました!!

ありがとうございました。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Javaの課題丸投げ 更新情報

Javaの課題丸投げのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング