ピースを動かす

ピースを１つ取り除いてできた空白の箇所を使って 移動するための処理を記述します。

空白の箇所の表現

どこに空白があるかを表すために、インスタンス変数を使います。

spxで空白の横方向の位置を、０～３の値で表すものとします。

spyで空白の縦方向の位置を、０～３の値で表すものとします。

例えば、spx=0, spy=2 のときは 上から３番目の左端が空白。

初期化

最初は右下隅のピースを取り除いた位置です。 したがって値は

spx = 3

spy = 3

空白箇所は右下のピースを取り除いたものですから、 配列要素の値は右下のピースの値としておきます。

ban[spx][spy] = 15

空白箇所の表示

paintComponent内に記述。

spx,spyで表された場所は空白であることを示すため、 １色で塗りつぶします。

クリック時の処理の演習ではcx,cyで示された位置を塗りつぶしていましたが、 spx,spyが示す箇所を塗りつぶすように修正します。

塗りつぶしの色は好みのものを指定してください。

ボタンが押されたときの処理

mousePressed内に記述。

クリック時の処理の演習では クリックされた座標x,yから対応する位置cx,cyを求めました。

cx,cyはmousePressedメソッド内でしか使わないので、(インスタンス変数ではなく)メソッド内の変数として宣言します。

このcx,cyとspx,spyの値を比較し、 クリックされた位置のピースが移動可能かどうか判定し、 可能な場合は移動する処理を記述します。

移動可能かどうかの判定

空白箇所の上下左右のとなりにあるピースの上でクリックされたときは、 そのピースをスライドして移動できる。

例えば丸で示した位置が空白のとき

クリックされた位置がA,B,C,Dのどれかであればよい。

空白の位置はspx,spyで、クリックされた位置はcx,cyで表されているので、 これを用いて判定を行う。

例えば、丸の位置が空白部分でAの位置でボタンが押された場合、変数の値は次のようになっています。

spx は 1

spy は 2

cx は 2

cy は 2

ピースを移動する処理

丸の位置が空白部分で、そのすぐ右のAの位置でボタンが押された場合を考えます。

次の処理を順に行ないます。

１）Aの位置にあるピースをすぐ左の空白位置に移動します。

２）空白位置をAの位置に変更します。

３）新しい空白位置に対応する値を代入します。

１）Aの位置どのピースがあるかはban[cx][cy]の値として記憶しており、 この値を空白位置である(spx,spy)に移すには

ban[spx][spy] = ban[cx][cy]

を行えばよい。

２）spx,spyの値を新しい空白位置の値であるcx,cyに修正します。

spx = cx

spy = cy

３）空白位置に対応する値(15)を代入します。

ban[spx][spy] = 15

以上をまとめると次のようになります。

ban[spx][spy] = ban[cx][cy];

spx = cx;

spy = cy;

ban[spx][spy] = 15;

空白の右隣のAの位置で考えましたが、 B,C,Dの位置でもこの命令でよいことを理解しておくこと。

プログラム

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Game6 extends JPanel implements MouseListener
{
Image img;
int[][] ban;
int spx, spy;
Game6()
{
ImageIcon ii = new ImageIcon( "game0.png");
img = ii. getImage();
addMouseListener( this);
ban = new int[ 4][ 4];
shokika();
spx = 3;
spy = 3;
}
void shokika()
{
盤の表現の演習
}
public void paintComponent( Graphics g)
{
int w, h, ax, ay, sx, sy, x, y;
w = 100;
h = 100;
for ( x = 0; x < 4; x++)
for ( y = 0; y < 4; y++)
{
ax = 盤の表示の演習 ;
ay = 盤の表示の演習 ;
sx = 盤の表示の演習 ;
sy = 盤の表示の演習 ;
g. drawImage( img, 画像を表示するの演習, this);
}
g. setColor( Color. blue);
g. fillRect( spx* 100, spy* 100, 100, 100);
}
public void mousePressed( MouseEvent e)
{
int x, y, cx, cy;
x = e. getX();
y = e. getY();
cx = クリック時の処理の演習;
cy = クリック時の処理の演習;
if ( 今回の演習 )
{
ban[ spx][ spy] = ban[ cx][ cy];
spx = cx;
spy = cy;
ban[ spx][ spy] = 15;
repaint();
}
}
public void mouseEntered( MouseEvent e) { }
public void mouseExited( MouseEvent e) { }
public void mouseReleased( MouseEvent e) { }
public void mouseClicked( MouseEvent e) { }
public static void main( String[] args)
{
JFrame f;
f = new JFrame();
f. setVisible( true);
f. setTitle( "15Game");
f. setSize( 420, 450);
f. setDefaultCloseOperation( JFrame. EXIT_ON_CLOSE);
f. add( new Game6() );
}
}

演習

ボタンが押された位置が空白箇所の隣であるかを判定する条件を 今回の演習 の位置に記述しプログラムを完成させなさい。