//================================================================ // Sliding Block Program // // Copyright(C) 1996 Hirofumi Fujiwara (arranged by Yo-zi Ito) // Copyright(C) 1998-1999 Nick Baxter // // v2.0 1997/12/2 Developed by Fujiwara and Ito // March 1998 enhancements by Jared Weinberger // Jan. 1999 bug fixed by Hirofumi Fujiwara // // Enhancements by Nick Baxter: // v3.0 Jun 22, 98 images for pieces; forward button; layout update; // solution indicator; piece labels; revised shadows // v3.1 Dec 04, 98 "color" keyword to assign piece color in datafile // v3.2 Dec 15, 98 "equiv" keyword in datafile to establish piece equivalence // v3.3 Dec 28, 98 adjusting previous piece does not increment counter // v3.4 Dec 29, 98 "labeloffset" keyword for precise label placement // v3.5 Jan 26, 99 Fujiwara's Netscape bug fix merged and enhanced // //================================================================ //================================================================ import java.awt.*; import java.applet.*; import java.lang.*; import java.io.*; import java.util.*; import java.net.*; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Slide Applet //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public class Slide extends Applet { final int BUTTON_H = 35; final int MSG_H = 35; final int COPY_H = 30; public Dimension app_size; // アプレットのサイズ Board board; // 盤 AudioClip sound = null; // 駒を動かす時の音 String filename; // 面データのファイル String nextfile; // 次に進む面のファイル名 private Label stepCounter; // step表示 Label doneMsg; ControlButton nextButton; ControlButton backButton; ControlButton redoButton; ControlButton replayButton; final Color backcolor = new Color(180,180,180); // background - grey final Color pagecolor = new Color(222,222,222); // final Color pagecolor = Color.white; // for white background final Color shadowLight = Color.white; // top, light shadow final Color shadowDark = Color.black; // bottom, dark shadow final Color piececolor = new Color(0.40f,0.40f,1.0f); // default piece color final Color limitcolor = Color.green; final Color hintcolor = Color.black; // goal line color final Color msgcolor = Color.red; //---------------------------------------------------------------- // 初期化 public void init() { String crMessage = "Slide Puzzle V3.5 " + "Copyright(c)1996-1999 Hirofumi Fujiwara, Nick Baxter"; System.out.println(crMessage); System.out.println("Version 3.5.1 - Netscape 4.5 fix part 1"); sound = getAudioClip(getCodeBase(),"tick.au"); filename = getParameter( "problemfile" ); app_size = this.size(); Rectangle r = new Rectangle(0,BUTTON_H + MSG_H, app_size.width, app_size.height - 2*BUTTON_H - MSG_H - COPY_H); board = new Board(this,r); Font f10 = new java.awt.Font( "Helvetica", 0, 10 ); Font f14 = new java.awt.Font( "Helvetica", 0, 14 ); Font bf16 = new java.awt.Font( "Helvetica", 1, 16 ); Font f20 = new java.awt.Font( "Helvetica", 0, 20 ); setBackground( pagecolor ); setLayout( new BorderLayout() ); { Panel p1 = new Panel(); add("North",p1); p1.setLayout(new FlowLayout()); backButton = new ControlButton(this,"Back"," Back "); backButton.setFont( f14 ); redoButton = new ControlButton(this,"Forward"," Forward "); redoButton.setFont( f14 ); p1.add(backButton); p1.add(redoButton); stepCounter = new Label(); stepCounter.setFont( f20 ); showcounter(); p1.add( stepCounter ); replayButton = new ControlButton(this,"Replay"," Restart "); replayButton.setFont( f14 ); p1.add(replayButton); p1.reshape(0,0,app_size.width,BUTTON_H); } setLayout(new BorderLayout()); { Panel p4 = new Panel(); add("North",p4); p4.setLayout(new FlowLayout()); doneMsg = new Label(); doneMsg.setFont(bf16); doneMsg.setForeground(msgcolor); doneMsg.setAlignment(Label.CENTER); doneMsg.setText(" "+ " "); p4.add(doneMsg); p4.reshape(0, BUTTON_H, app_size.width, MSG_H); } setLayout(new BorderLayout()); { Panel p3 = new Panel(); add("South", p3 ); p3.setLayout( new FlowLayout()); nextButton = new ControlButton(this,"Next"," Go to next problem "); nextButton.setFont(f14); p3.add(nextButton); p3.reshape( 0, app_size.height - BUTTON_H - COPY_H, app_size.width, BUTTON_H); } setLayout(new BorderLayout()); { Panel p2 = new Panel(); p2.setLayout( new FlowLayout()); add("South", p2 ); Label copyright = new Label( crMessage, Label.CENTER ); copyright.setFont( f10 ); p2.add( copyright ); p2.reshape( 0, app_size.height - COPY_H, app_size.width, COPY_H); } replay(); } //---------------------------------------------------------------- // カウンタ表示 public void showcounter() { if(board.minStep==0) stepCounter.setText( " Step "+board.step+" " ); else stepCounter.setText( " Step "+board.step+"/"+ board.minStep+" " ); } //---------------------------------------------------------------- // カウンタ表示 public void showMsg(String msg) { doneMsg.setText( msg ); } //---------------------------------------------------------------- // 再スタート public void replay() { board.setup(filename); showcounter(); backButton.disable(); redoButton.disable(); if(nextfile == null) nextButton.disable(); else enable(); paint( getGraphics() ); } //---------------------------------------------------------------- // 次の面へ public void next() { if(nextfile != null) filename = nextfile; replay(); } //---------------------------------------------------------------- // マウス操作 public boolean mouseDown( Event evt, int x, int y ) { board.mouseDown(x,y); return true; } public boolean mouseDrag( Event evt, int x, int y ) { board.mouseDrag(x,y); return true; } public boolean mouseUp( Event evt, int x, int y ) { board.mouseUp(x,y); return true; } //---------------------------------------------------------------- // ペイント public void paint( Graphics g ) { // boolean flg = g.drawImage(backImage,0,CTRLPANEL_H*2, // app_size.width,app_size.height-CTRLPANEL_H*2-COPY_H, // shadowLight, null); board.paintHint(g); board.paint(g); } public void repaint() { paint(getGraphics()); } } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // ControlButton 制御ボタンクラス //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class ControlButton extends Button { Slide slide; String name; // ボタンの名前 ControlButton( Slide s, String str, String label ) { super(); slide = s; name = str; setLabel( label ); } //---------------------------------------------------------------- // ボタン操作 public boolean action( Event evt, Object obj ) { if(name.equals("Replay")) slide.replay(); if(name.equals("Back")) slide.board.backHistory(); if(name.equals("Forward")) slide.board.forwardHistory(); if(name.equals("Next")) slide.next(); return true; } } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Board 盤内での操作を管理するクラス //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class Board extends Rectangle { final int maxPiece = 32; //一駒のブロック数の上限 final int maxHistory = 512; //ヒストリ上限 public Block blocks[][]; //盤を表す配列 String targetBlocks[][]; //目標とする状態 char hintBlocks[][]; int ax,ay; //盤のサイズ Slide slide; // 呼び出した Applet int unit; //1ブロックの大きさ int minStep; //目標ステップ数 int step; //現在のステップ数 private Rectangle req; //盤の大きさの限界 Piece pieces[]; //駒 int piecen; //駒の数 Piece currentPiece; //ドラッグ中の駒 Point dragPoint; //ドラッグ現在地 Point dPoint; //ドラッグ中の移動距離 boolean dragFlag; //ドラッグ中 String boardType = "none"; boolean painting; //描画中 Piece pieceHistory[]; //駒のヒストリ Point pointHistory[]; //位置のヒストリ int historyCount; //ヒストリ現在地 int redoLimit; int originalRedoLimit; int originalX; int originalY; boolean adjusting; //---------------------------------------------------------------- // コンストラクタ s:呼び出したApplet r:盤の位置と大きさ(最大) Board(Slide s,Rectangle r){ pieces = new Piece[maxPiece]; slide = s; unit = 16; x = y = 0; req = r; step = 0; pieceHistory = new Piece[maxHistory]; pointHistory = new Point[maxHistory]; } //---------------------------------------------------------------- // 初期化 filename:面データのファイル名 public void setup(String filename){ minStep = step = 0; targetBlocks = null; hintBlocks = null; currentPiece = null; painting = false; ax = ay = 0; piecen = 0; dragFlag = false; loadData(filename); if(ax==0 || ay==0){ ax = ay = 1; System.out.println("File read error!"); } int u1 = (int)(req.width*0.92)/ax; int u2 = (int)(req.height*0.92)/ay; unit = (u10) ddx=2*radius-dx; else ddx=dx-2*radius; // dPoint.x-=ddx; // dx+=ddx; // System.out.println("BOOST-x: "+dx); // dx2 = currentPiece.moveX(dPoint.x,dPoint.y,dx); // break; // } // } // } dPoint.x += dx2; if(dx2!=dx && dx2!=0 && currentPiece.moveX(dPoint.x,dPoint.y,dx)==0) { f = true; } int dy2 = currentPiece.moveY(dPoint.x,dPoint.y,dy); // if (dy!=0 && dy2==0) { // for (int d=-radius;d<=radius;d++) { // dy2 = currentPiece.moveY(dPoint.x-d,dPoint.y,dy); // if (dy2 != 0) { // System.out.println("ADJUST-x: "+ -d); // dPoint.x-=d; // dx+=d; // // int ddy; // if(dy>0) ddy=2*radius-dy; else ddy=dy-2*radius; // dPoint.y-=ddy; // dy+=ddy; // System.out.println("BOOST-y: "+dy); // dy2 = currentPiece.moveY(dPoint.x,dPoint.y,dy); // break; // } // } // } dPoint.y += dy2; if(dy2!=dx && dy2!=0 && currentPiece.moveY(dPoint.x,dPoint.y,dy)==0){ f = true; } dragPoint.move(v,w); currentPiece.update(slide.getGraphics(),dPoint.x,dPoint.y); if(f) slide.sound.play(); dragFlag = true; painting = false; } //---------------------------------------------------------------- // マウスを離した時 v,w:座標 public void mouseUp(int v, int w){ v-=x; w-=y; if(!dragFlag) return; dragFlag = false; int offx = (dPoint.x+unit/2+unit*1024)/unit-1024; int offy = (dPoint.y+unit/2+unit*1024)/unit-1024; // see if this move is really same as Back if (historyCount>0) if (pieceHistory[historyCount-1].cid==currentPiece.cid && pointHistory[historyCount-1].x == -offx && pointHistory[historyCount-1].y == -offy) { backHistory(); return; } // see if this move is really same as Forward if (historyCount0) && (pieceHistory[historyCount-1].cid==currentPiece.cid) ) { int offxx = pointHistory[historyCount-1].x + offx; int offyy = pointHistory[historyCount-1].y + offy; System.out.println("Replace " + String.valueOf(step) + ": " + currentPiece.cid + ", "+String.valueOf(offxx)+","+ String.valueOf(offyy)); // check to see if Forward should be enabled or disabled if ((originalRedoLimit>0) && (offxx==originalX) && (offyy==originalY)) { redoLimit = originalRedoLimit; if (historyCountminStep && minStep>0) slide.showMsg("Done!"); if (minStep==0) slide.showMsg("Done - please report results!"); if (step==minStep) slide.showMsg("Complete with minimum moves!!"); if (step= maxHistory){ System.out.println("Reduce history"); int i=0; for(int j=maxHistory/2; j= 0) continue; return false; } return true; } //---------------------------------------------------------------- // Blockの形状設定 public void setBlockShape(){ for(int j=ay;--j>=0;) for(int i=ax;--i>=0;) { Block bk = null; char c = '.'; try{ bk = blocks[i][j]; c = bk.piece.cid; } catch( Exception e ){ continue; } try{ if(blocks[i-1][j].piece.cid==c) bk.linkW=true; } catch( Exception e ){} try{ if(blocks[i+1][j].piece.cid==c) bk.linkE=true; } catch( Exception e ){} try{ if(blocks[i][j-1].piece.cid==c) bk.linkN=true; } catch( Exception e ){} try{ if(blocks[i][j+1].piece.cid==c) bk.linkS=true; } catch( Exception e ){} } } //---------------------------------------------------------------- // 盤の内外判定 public boolean isinside(int xx, int yy) { if( xx < 0 || xx >= ax ) return false; if( yy < 0 || yy >= ay ) return false; Block blk = blocks[xx][yy]; if( blk != null && blk.outside) return false; return true; } //---------------------------------------------------------------- // returns true if is a blocking block public boolean isblocking(int xx, int yy) { if( xx < 0 || xx >= ax ) return false; if( yy < 0 || yy >= ay ) return false; Block blk = blocks[xx][yy]; if( blk != null && blk.outside) return true; return false; } private void borderpaint(Graphics g){ int thick = 4; int bWidth; int nwDelta[],swDelta[],neDelta[],seDelta[]; Color borderColor; if (isSolution()) { borderColor = slide.msgcolor; bWidth = thick; } else { borderColor = slide.shadowDark; bWidth = 1; } nwDelta = new int[thick+1]; swDelta = new int[thick+1]; neDelta = new int[thick+1]; seDelta = new int[thick+1]; for(int j=ay;--j>=0;){ int y0 = y + unit*j; for(int i=ax;--i>=0;){ int x0 = x + unit*i; if( ! isinside(i,j) ) { continue; } for (int b=0;b<=thick;b++) nwDelta[b]=swDelta[b]=neDelta[b]=seDelta[b] = b+1; if (isinside(i-1,j-1)) for (int b=0;b<=thick;b++) nwDelta[b] = 1-nwDelta[b]; if (isinside(i-1,j+1)) for (int b=0;b<=thick;b++) swDelta[b] = 1-swDelta[b]; if (isinside(i+1,j-1)) for (int b=0;b<=thick;b++) neDelta[b] = 1-neDelta[b]; if (isinside(i+1,j+1)) for (int b=0;b<=thick;b++) seDelta[b] = 1-seDelta[b]; if( ! isinside(i-1,j) ) { // 左側 for (int b=0;b<=thick;b++) { if (b==0) g.setColor(slide.shadowLight); else if (b>bWidth) g.setColor(slide.backcolor); else g.setColor(borderColor); g.drawLine(x0-b-1,y0-nwDelta[b], x0-b-1,y0+unit-1+swDelta[b]); } } if( ! isinside(i+1,j) ) { // 右側 for (int b=0;b<=thick;b++) { if (b==0) g.setColor(slide.shadowLight); else if (b>bWidth) g.setColor(slide.backcolor); else g.setColor(borderColor); g.drawLine(x0+unit+b,y0-neDelta[b], x0+unit+b,y0+unit-1+seDelta[b]); } } if( ! isinside(i,j-1) ) { // 上側 for (int b=0;b<=thick;b++) { if (b==0) g.setColor(slide.shadowLight); else if (b>bWidth) g.setColor(slide.backcolor); else g.setColor(borderColor); g.drawLine(x0-nwDelta[b],y0-1-b, x0+unit-1+neDelta[b],y0-1-b); } } if( ! isinside(i,j+1) ) { // 下側 for (int b=0;b<=thick;b++) { if (b==0) g.setColor(slide.shadowLight); else if (b>bWidth) g.setColor(slide.backcolor); else g.setColor(borderColor); g.drawLine(x0-swDelta[b],y0+unit+b, x0+unit-1+seDelta[b],y0+unit+b); } } } } for(int j=ay;--j>=0;){ int y0 = y + unit*j; for(int i=ax;--i>=0;){ int x0 = x + unit*i; if( isblocking(i,j) ) { Block blk = blocks[i][j]; if( blk.image != null) { boolean flg = g.drawImage(blk.image, x0, y0, blk.width*unit*blk.wFactor, blk.height*unit*blk.hFactor, slide.shadowLight, null); } } } } } //---------------------------------------------------------------- // 盤内ペイント public void paint(Graphics g){ borderpaint( g); // g.setColor( slide.backcolor ); // g.fillRect(x,y,width,height); // g.setColor( slide.shadowLight ); // g.drawLine(x,y+height,x+width,y+height); // g.drawLine(x+width,y,x+width,y+height); // g.drawLine(x-1,y+height+1,x+width+1,y+height+1); // g.drawLine(x+width+1,y-1,x+width+1,y+height+1); // g.setColor( slide.shadowDark ); // g.drawLine(x-1,y-1,x-1,y+height-1); // g.drawLine(x-1,y-1,x+width-1,y-1); // g.drawLine(x-2,y-2,x-2,y+height); // g.drawLine(x-2,y-2,x+width,y-2); for(int j=ay;--j>=0;){ for(int i=ax;--i>=0;){ Block blk = blocks[i][j]; if( blk == null ) { g.setColor( slide.backcolor ); g.fillRect(x+i*unit, y+j*unit, unit, unit); } else if( ! blk.outside ) { blk.paint(g); } } } } //---------------------------------------------------------------- // 目標を示す線の描画 public void paintHint(Graphics g){ char c; int hWidth = 4; if (hintBlocks==null) return; g.setColor( slide.hintcolor ); for(int v=ax; --v>=0;){ c = hintBlocks[v][0]; if(c!='.' && c!='#'){ g.fillRect(x+v*unit,y-10,unit,hWidth); }else{ g.clearRect(x+v*unit,y-10,unit,hWidth); } c = hintBlocks[v][ay-1]; if(c!='.' && c!='#'){ g.fillRect(x+v*unit,y+height+(10-hWidth),unit,hWidth); }else{ g.clearRect(x+v*unit,y+height+(10-hWidth),unit,hWidth); } } for(int w=ay; --w>=0;){ c = hintBlocks[0][w]; if(c!='.' && c!='#'){ g.fillRect(x-10,y+w*unit,hWidth,unit); }else{ g.clearRect(x-10,y+w*unit,hWidth,unit); } c = hintBlocks[ax-1][w]; if(c!='.' && c!='#'){ g.fillRect(x+width+(10-hWidth),y+w*unit,hWidth,unit); }else{ g.clearRect(x+width+(10-hWidth),y+w*unit,hWidth,unit); } } } //---------------------------------------------------------------- // 問題、解答の読み込み filename:面データのファイル名 private void loadData(String filename){ URL url; DataInputStream file; try { url = new URL( slide.getDocumentBase(), filename ); System.out.println("Load: "+url); file = new DataInputStream( url.openStream() ); } catch( MalformedURLException e ) { slide.showStatus( "file name error : " + filename ); return; } catch( IOException e ) { slide.showStatus( "file open error : " + filename ); return; } try { slide.nextfile = null; String line; StringBuffer str = new StringBuffer(""); int y = 0; MediaTracker mTracker; mTracker = new MediaTracker(slide); nextline: for(;;) { line=file.readLine(); if( line == null ) break; if( ';' == line.charAt(0) ) continue; // System.out.println( "line:"+line ); StringTokenizer st = new StringTokenizer(line); try { String tk = st.nextToken(); if( tk.equals("size") ) { tk = st.nextToken(); ax = (Integer.valueOf(tk)). intValue(); tk = st.nextToken(); ay = (Integer.valueOf(tk)). intValue(); // System.out.println("\tboard size=" + String.valueOf(ax) + "," + String.valueOf(ay)); blocks = new Block[ax][ay]; targetBlocks = new String[ax][ay]; continue nextline; } if (tk.equals("image") ) { tk = st.nextToken(); int row = (Integer.valueOf(tk)).intValue(); tk = st.nextToken(); int col = (Integer.valueOf(tk)).intValue(); tk = st.nextToken(); blocks[col][row].image = slide.getImage(slide.getCodeBase(),tk); tk = st.nextToken(); blocks[col][row].hFactor = (Integer.valueOf(tk)).intValue(); tk = st.nextToken(); blocks[col][row].wFactor = (Integer.valueOf(tk)).intValue(); mTracker.addImage(blocks[col][row].image,0, blocks[col][row].wFactor*unit, blocks[col][row].hFactor*unit); continue nextline; } if (tk.equals("label") ) { tk = st.nextToken(); char x = tk.charAt(0); int k; for (k=piecen;--k>=0;) { if (pieces[k].cid == x) break; } tk = st.nextToken(); if (k>=0) pieces[k].setLabel(tk); continue nextline; } if (tk.equals("labeloffset") ) { tk = st.nextToken(); char x = tk.charAt(0); int k; for (k=piecen;--k>=0;) { if (pieces[k].cid == x) break; } tk = st.nextToken(); int offsetX = (Integer.valueOf(tk)).intValue(); tk = st.nextToken(); int offsetY = (Integer.valueOf(tk)).intValue(); if (k>=0) pieces[k].setLabelOffset(offsetX,offsetY); continue nextline; } if (tk.equals("color") ) { tk = st.nextToken(); char x = tk.charAt(0); int k; for (k=piecen;--k>=0;) { if (pieces[k].cid == x) break; } tk = st.nextToken(); int r = (Integer.valueOf(tk)).intValue(); tk = st.nextToken(); int g = (Integer.valueOf(tk)).intValue(); tk = st.nextToken(); int b = (Integer.valueOf(tk)).intValue(); if (k>=0) pieces[k].setColor(r,g,b); continue nextline; } if (tk.equals("equiv") ) { tk = st.nextToken(); for (int j=0;j=0 ) { targetBlocks[i][j] = tk; } } continue nextline; } if( tk.equals("next")){ tk = st.nextToken(); slide.nextfile = tk; // System.out.println("\tnext:" + tk); boardType="none"; } if( tk.equals("step")){ tk = st.nextToken(); minStep = (Integer.valueOf(tk)) .intValue(); boardType="none"; } if( tk.equals("initial") ) { // System.out.println("\tload initial"); boardType = tk; str = new StringBuffer(""); y = 0; continue nextline; } if( tk.equals("hint") ) { // System.out.println("\tload hint"); boardType = tk; hintBlocks = new char[ax][ay]; str = new StringBuffer(""); y = 0; continue nextline; } if( tk.equals("target") ) { // System.out.println("\tload target"); boardType = tk; str = new StringBuffer(""); y = 0; continue nextline; } if( tk.equals("end") ) { break nextline; } if( ! boardType.equals("none") ) { ++y; str.append( line ); if( y >= ay ) { setupData(str.toString()); boardType="none"; } } } catch( NoSuchElementException e ) { System.out.println( "No such element(s).(file error)"); } } try { mTracker.waitForID(0); } catch(InterruptedException e) { System.out.println("MediaTracker error"); } } catch( IOException e ) {} System.out.println( "-- End of LoadData--" ); } //---------------------------------------------------------------- // 初期配列/目標 データを配列に読み込む str:文字列化した面データ private void setupData(String str) { int idx = 0; if(boardType.equals("initial")) { for(int j=0;j=0;){ if(pieces[k].cid==c) break; } if(k<0){ k = piecen; pieces[piecen++] = new Piece(this,c); } pieces[k].add(bk); } } } if(boardType.equals("hint")) { for(int j=0;j=0){ x2 = x1; w2 = (dx=0){ y2 = y1; h2 = (dy unit-adj) dx = unit-adj; return dx; }else{ offx = (dx>0)? offx+1 : offx-1; for(int i=blockn;--i>=0;){ Block bk = blocks[i]; Block bk2 = null; try{ bk2 = board.blocks[bk.x+offx][bk.y+offy]; if(bk2 != null) { if( bk2.outside || bk2.piece.cid != cid) { return 0; } } if(y%unit != 0){ bk2 = board.blocks[bk.x+offx][bk.y+offy+1]; if(bk2 != null && bk2.piece.cid != cid) return 0; } } catch( Exception e ){return 0;} } if(dx > unit) dx = unit; if(dx <-unit) dx = -unit; return dx; } } //---------------------------------------------------------------- // Y方向移動チェック x,y:元の位置からの相対位置 dy:移動量 public int moveY(int x,int y,int dy){ if(dy == 0) return 0; int unit = board.unit; int offx = (x+unit*1024)/unit-1024; int offy = (y+unit*1024)/unit-1024; int adj = y-offy*unit; if(adj != 0){ if(dy < -adj) dy = -adj; if(dy > unit-adj) dy = unit-adj; return dy; }else{ offy = (dy>0)? offy+1 : offy-1; for(int i=blockn;--i>=0;){ Block bk = blocks[i]; Block bk2 = null; try{ bk2 = board.blocks[bk.x+offx][bk.y+offy]; if(bk2 != null) { if( bk2.outside || bk2.piece.cid != cid) { return 0; } } if(x%unit !=0){ bk2 = board.blocks[bk.x+offx+1][bk.y+offy]; if(bk2 != null && bk2.piece.cid != cid) return 0; } } catch( Exception e ){return 0;} } if(dy > unit) dy = unit; if(dy <-unit) dy = -unit; return dy; } } //------------------------------------------------------------ // 実際の移動 dx,dy:盤の配列上の相対位置 public void move( int dx, int dy ) { int unit = board.unit; int i; for(i=blockn;--i>=0;){ Block bk = blocks[i]; board.blocks[bk.x][bk.y] = null; } for(i=blockn;--i>=0;){ Block bk = blocks[i]; blocks[i].move(bk.x+dx,bk.y+dy); board.blocks[bk.x][bk.y] = blocks[i]; } } //---------------------------------------------------------------- // 描画ルーチンの初期化 updateを使い始める前に使う public void resetAdjust(){ delta.x = delta.y = 0; } //---------------------------------------------------------------- // ドラッグ中の描画 dx,dy:元の位置からの相対位置 public void update(Graphics g,int dx,int dy){ if(delta.x == dx && delta.y == dy) return; for(int i=blockn;--i>=0;){ blocks[i].clear(g,delta.x,delta.y,dx-delta.x,dy-delta.y); } delta.x = dx; delta.y = dy; for(int i=blockn;--i>=0;){ blocks[i].paint(g,dx,dy); } } } //================================================================ // End of File //================================================================