(c)도경구 version 1.0 (2022/10/26)
public class PuzzlePiece {
private int face;
public int face() {
return face;
}
public PuzzlePiece(int n) {
face = n;
}
}
public class SlidePuzzleBoard {
private PuzzlePiece[][] board;
private int empty_row;
private int empty_col;
public PuzzlePiece[][] board() { return board; }
public SlidePuzzleBoard() {
board = new PuzzlePiece[4][4];
int number = 15;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) {
board[i][j] = new PuzzlePiece(number);
number -= 1;
}
board[3][3] = null;
empty_row = 3;
empty_col = 3;
}
public boolean move(int n) {
int row, col;
if (found(n,empty_row-1, empty_col)) {
row = empty_row-1;
col = empty_col;
}
else if (found(n,empty_row+1, empty_col)) {
row = empty_row+1;
col = empty_col;
}
else if (found(n,empty_row, empty_col-1)) {
row = empty_row;
col = empty_col-1;
}
else if (found(n,empty_row, empty_col+1)) {
row = empty_row;
col = empty_col+1;
}
else
return false;
board[empty_row][empty_col] = board[row][col];
board[row][col] = null;
empty_row = row;
empty_col = col;
return true;
}
private boolean found(int n, int r, int c) {
if (r >= 0 && r <= 3 && c >= 0 && c <= 3)
return board[r][c].face() == n;
else
return false;
}
}
import java.awt.*;
import javax.swing.*;
public class PuzzleWriter extends JPanel {
private SlidePuzzleBoard puzzle;
private final int SIZE; // the size of a puzzle piece in pixel
public PuzzleWriter(SlidePuzzleBoard p) {
puzzle = p;
SIZE = 30;
JFrame f = new JFrame();
f.getContentPane().add(this);
f.setLocation(550,100);
f.setTitle("Slide Puzzle");
f.setSize(SIZE*6, SIZE*6+28);
f.setVisible(true);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public void paintComponent(Graphics g) {
g.setColor(Color.YELLOW);
g.fillRect(0, 0, SIZE*6, SIZE*6);
PuzzlePiece[][] r = puzzle.board();
for (int i = 0; i < 4; i = i + 1) {
for (int j = 0; j < 4; j = j + 1) {
paintPiece(g, r[i][j], i, j);
}
}
}
private void paintPiece(Graphics g, PuzzlePiece p, int i, int j) {
int x = SIZE + (SIZE * j);
int y = SIZE + (SIZE * i);
if (p != null) {
g.setColor(Color.WHITE);
g.fillRect(x, y, SIZE, SIZE);
g.setColor(Color.BLACK);
g.drawRect(x, y, SIZE, SIZE);
int face_value = p.face();
if (face_value < 10)
g.drawString(face_value + "", x+11, y+20);
else
g.drawString(face_value + "", x+7, y+20);
}
else {
g.setColor(Color.BLACK);
g.fillRect(x, y, SIZE, SIZE);
}
}
public void displayPuzzleBoard() {
this.repaint();
}
public void showNoMove(String s) {
JOptionPane.showMessageDialog(null, "Error: " + s );
}
}
import javax.swing.*;
public class PuzzleController {
private SlidePuzzleBoard puzzle;
private PuzzleWriter writer;
public PuzzleController(SlidePuzzleBoard p, PuzzleWriter w) {
puzzle = p;
writer = w;
}
public void play() {
while (true) {
writer.displayPuzzleBoard();
String input = JOptionPane.showInputDialog("Your move:");
int n = Integer.parseInt(input);
if (! puzzle.move(n))
writer.showNoMove("Cannot move.");
}
}
}
public class PuzzleStarter {
public static void main(String[] args) {
SlidePuzzleBoard puzzle = new SlidePuzzleBoard();
PuzzleWriter writer = new PuzzleWriter(puzzle);
new PuzzleController(puzzle,writer).play();
}
}
public class Card {
public static final String SPADES = "spades";
public static final String HEARTS = "hearts";
public static final String DIAMONDS = "diamonds";
public static final String CLUBS = "clubs";
public static final int ACE = 1;
public static final int JACK = 11;
public static final int QUEEN = 12;
public static final int KING = 13;
public static final int SIZE_OF_ONE_SUIT = 12;
private String suit;
private int rank;
public Card(String s, int r) {
suit = s;
rank = r;
}
public String suit() {
return suit;
}
public int rank() {
return rank;
}
public boolean equals(Card c) {
return suit.equals(c.suit()) && rank == c.rank();
}
}
public class CardDeck {
private int card_count; // 남은 카드 수
private Card[] deck = new Card[4 * Card.SIZE_OF_ONE_SUIT];
// Invariant: deck[0], .., decl[card_count-1] 에 카드가 있다.
public CardDeck() {
createDeck();
}
private void createDeck() {
createSuit(Card.SPADES);
createSuit(Card.HEARTS);
createSuit(Card.CLUBS);
createSuit(Card.DIAMONDS);
}
private void createSuit(String which_suit) {
for(int i = 1; i <= Card.SIZE_OF_ONE_SUIT; i++) {
deck[card_count] = new Card(which_suit, i);
card_count = card_count + 1;
}
}
/** newCard - 임의의 새 카드 한 장을 뽑아 줌
* @return 카드 덱에서 임의로 한 장을 뽑아 리턴
* 없으면 카드 1벌을 새로 만들고 한 장을 뽑아 리턴 */
public Card newCard() {
if (! this.moreCards())
createDeck();
int index = (int)(Math.random() * card_count);
Card card_to_deal = deck[index];
for (int i = index+1; i < card_count; i++)
deck[i-1] = deck[i];
card_count = card_count - 1;
return card_to_deal;
}
/** moreCards - 카드 덱에 카드가 남아있는지 알려줌
* @return 있으면 true, 없으면 false */
public boolean moreCards() {
return card_count > 0;
}
}
public interface CardPlayerBehavior {
/** wantsACard - 카드 한 장을 받겠는지 답한다.
* @return 카드를 받고 싶으면 true, 아니면 false */
public boolean wantsACard();
/** receiveCard - 카드를 한장 받는다. 한도(배열 hand의 크기)를 초과하면 받을 수 없다.
* @param c - 카드
* @return 성공적으로 받았으면 true, 그렇지 않으면 false */
public boolean receiveCard(Card c);
}
public class Dealer {
CardDeck deck;
public Dealer() {
deck = new CardDeck();
}
public void dealTo(CardPlayerBehavior p) {
while (p.wantsACard()) {
Card c = deck.newCard();
p.receiveCard(c);
}
}
public static void main(String[] args) {
Dealer d = new Dealer();
HumanPlayer p = new HumanPlayer(3);
d.dealTo(p);
Card[] hand = p.showCards();
for (int i = 0; i < hand.length; i++) {
System.out.println(hand[i].getSuit() + " " + hand[i].getRank());
}
}
}
public abstract class CardPlayer implements CardPlayerBehavior {
private Card[] hand; // 갖고 있는 카드
private int card_count; // 갖고 있는 카드의 장 수
/** Constructor CardPlayer - max_cards 카드를 수용가능한 Card 배열 객체를 만들어 CardPlayer 생성
* @param max_cards - 들고 있을 수 있는 카드의 최대 장수 */
public CardPlayer(int max_cards) {
hand = new Card[max_cards];
card_count = 0;
}
/** wantsACard - 카드 한 장을 받겠는지 답한다.
* @return 카드를 받고 싶으면 true, 아니면 false */
public abstract boolean wantsACard();
/** receiveCard - 카드를 한장 받는다. 한도(배열 hand의 크기)를 초과하면 받을 수 없다.
* @param c - 카드
* @return 성공적으로 받았으면 true, 그렇지 않으면 false */
public boolean receiveCard(Card c) {
if (card_count < hand.length) {
hand[card_count] = c;
card_count += 1;
return true;
}
else
return false;
}
/** showCards - 들고 있는 카드를 내준다.
* @return 들고 있는 카드 전체 */
public Card[] showCards() {
Card[] card = new Card[card_count];
for (int i = 0; i < card_count; i++)
card[i] = hand[i];
return card;
}
}
import javax.swing.*;
public class HumanPlayer extends CardPlayer {
public HumanPlayer(int max_cards) {
super(max_cards);
}
public boolean wantsACard() {
String response = JOptionPane.showInputDialog("한장 더 드릴까요? (Y/N)");
return response.equals("Y");
}
}
import javax.swing.JOptionPane;
public class ComputerPlayer extends CardPlayer {
public ComputerPlayer(int max_cards) {
super(max_cards);
}
public boolean wantsACard() {
boolean decision;
Card[] cards = showCards();
// 게임에 따라 다른 전략을 세움
return true;
}
}