Board coverage V1.0

Source: Internet
Author: User
Tags getcolor gety

What is board coverage? Board coverage covers all squares except special squares on a given special board with four different forms of L-shaped bone cards, and no two L-type dominoes can overlap. Yes, that's easy! This is an example application that I learned when I used credit-based algorithms in university algorithms. I learned this algorithm and practiced Java swing (mainly because of my graduation design for others ), this is something I got during college.
First, paste the final result diagram:

 

It is not difficult to see from the interface that there are checkerboard, checkerboard square, bone card (4 types) and so on.

 

1. Checker (chesspanel): The checker is represented by a jpanel, which consists of chessboxes. The main tasks in chesspanel are:

A. initialize the special square:
/** <Br/> * initialize a special square <br/> * @ Param Dr special square abscissa <br/> * @ Param DC special square ordinate <br/> */< br/> Public void initspecificpanelocation (int dr, int DC) {<br/> This. dr = Dr; <br/> This. dc = Dc; <br/> // initialization <br/> for (INT I = 0; I <boxes. length; I ++) {<br/> for (Int J = 0; j <Boxes [I]. length; j ++) {<br/> // the chessboard is not overwritten during initialization, only the special square is black covered <br/> Boxes [I] [J] = new chessbox (I = getdr () & J = getdc ())? Kboxcolor: chesscolor); <br/> Boxes [I] [J]. setcovered (I = getdr () & J = getdc ())? True: false); <br/>}< br/> // set the border style of the chessboard <br/> setborder (New etchedborder (etchedborder. raised, color. white, new color (148,145,140); <br/> // stores the correct layout of the checkerboard for convenient calling <br/> coveralgorithm. savemovemethod (false, getdr (), getdc (), lens); <br/> repaint (); <br/>}< br/>

 

B. initialize the checkerboard. Same as above, the Code is a bit repetitive when I write it here. I didn't take it into consideration at the time. I found it when I was reading it.

C. Implement the paintcomponent method and draw a board. Here is the draw line. The square separated by these lines is the chessboard, where each square has its own color attributes.
@ Override <br/> Public void paintcomponent (Graphics g) {<br/> super. paintcomponent (g); <br/> // draw a chessboard <br/> for (INT I = 0; I <boxes. length; I ++) {<br/> for (Int J = 0; j <Boxes [I]. length; j ++) {<br/> G. setcolor (boxes [I] [J]. getcolor (); <br/> G. fill3drect (I * (size/lens), J * (size/lens), size/lens, size/lens, true ); <br/>}< br/> // draw a vertical midline <br/> G. setcolor (color. pink); <br/> G. drawline (0, size/2-2, size-2, size/2-2); <br/> G. drawline (size/2-2, 0, size/2-2, size-2); <br/>}< br/>

 

2. chessbox on the board: it is the chessbox used above. There is no logic code in the chessbox. It has only a few attributes: color, whether it is overwritten, And the size (this is redundant, because the sizes are the same ).

 

3. dominopanel: this class is complicated. It may be the reason for poor design. This class is large and has almost 700 rows. Dominopanel is also composed of chessboxes. A dominopanel is composed of four chessboxes, and 4*4 = 16 chessboxes are required. The four dominoes are defined as follows:

The following figure shows how to construct a bone card: color the bone card (four chessboxes) with the result of Style & Key to get the final bone card style.
// One of the dominoes styles and the "&" (each of them is connected one by one) to obtain the dominoes shape <br/> int key = 0x20; <br/> int r = new random (). nextint (255); <br/> int G = new random (). nextint (255); <br/> int B = new random (). nextint (255); <br/> color = new color (R, G, B); <br/> for (INT I = 0; I <boxes. length; I ++) {<br/> for (Int J = 0; j <Boxes [I]. length; j ++) {<br/> Boolean iscoloring = (Style & Key )! = 0); <br/> Boxes [I] [J] = new chessbox (iscoloring? Color: NULL); <br/> key >>=1; <br/>}< br/> key >>=2; <br/>}< br/>

 

The second is the effect of dragging the bone card with the mouse. This effect is very easy. When the mouse is pressed and the mouse is dragged, the coordinates x and y of the mouse are recorded, when the mouse is dragged and the mouse is not released (that is, in the drag mouse event method), set the position of this card as follows (panel is a reference object of the card, the dominoes class inherits a jpanel ):
Setlocation (panel. getx () + E. getx ()-X, panel. Gety () + E. Gety ()-y );
In this way, you can achieve the simple effect of the Dominator following the mouse, and then set the appearance of the drag to achieve the effect in the game, which is very easy to understand.

 

Then the paintcomponent method of dominopanel is implemented: There is a drag-and-drop (with a small border) and other appearances.

@ Override <br/> Public void paintcomponent (Graphics g) {<br/> super. paintcomponent (g); <br/> graphics2d g2d = (graphics2d) g; <br/> // specifies the appearance of the card when dragging. <br/> If (isdragdomino ()) {<br/> for (INT I = 0; I <boxes. length; I ++) {<br/> for (Int J = 0; j <Boxes [I]. length; j ++) {<br/> color = Boxes [I] [J]. getcolor (); <br/> If (color! = NULL) {<br/> G. setcolor (boxes [I] [J]. getcolor (); <br/> G. fill3drect (j = 0? 2: cellsize, I = 0? 2: cellsize, <br/> cellsize-4, cellsize-4, true ); <br/>}< br/> rectangle rbig = new rectangle (0, 0, 2 * cellsize-2, 2 * cellsize-2); <br/> rectangle rsmall = new rectangle (<br/> (getstyle () = dominopanel. styles [0]) | (getstyle () = dominopanel. styles [2])? 0: cellsize, <br/> (getstyle () = dominopanel. styles [0]) | (getstyle () = dominopanel. styles [1])? 0: cellsize, <br/> cellsize-2, cellsize-2); <br/> area Area = new area (rbig); <br/> area. subtract (New Area (rsmall); <br/> g2d. setcolor (color. red); <br/> g2d. draw (area); <br/>} else {// appearance of the dominoes in other cases <br/> for (INT I = 0; I <boxes. length; I ++) {<br/> for (Int J = 0; j <Boxes [I]. length; j ++) {<br/> color = Boxes [I] [J]. getcolor (); <br/> If (color! = NULL) {<br/> G. setcolor (boxes [I] [J]. getcolor (); <br/> G. fill3drect (J * cellsize, I * cellsize, true ); <br/>}< br/>}

 

Finally, there are some details to be processed. 1. Drag the bone card (the bone card is a jpanel, and this is a square). Therefore, you need to judge whether the mouse will not be moved if the color is null; 2. The border is displayed only when the mouse is inside the board. 3. When the mouse is dragged to the Board, the dominoes must be placed on the boards of the four chessboxes marked with good lines, it cannot be dragged to where it is to be dragged. 4. Implement rankings; 5. Error prompt; 6. Automatic demonstration (during Automatic demonstration, directly use the linear equation to let the card go straight. For more information, see the code.

 

Well, the things we can see from the interface are almost summarized. Below is a very important algorithm. I think the algorithm can be optimized, however, at that time, the level was limited, so I didn't have to worry about it any more. I hope the prawns can help me see it. Thank you. The algorithm has four words: divide and conquer. If you understand it, you can understand it. Needless to say, it is useless. The algorithm is as follows (the source code in the game has not been changed): The main thing to do here is to record the correct steps, define a hashmap to store the correct routing (overwrite the main algorithm by traversing the Board), where the key stores the vertices in the upper left corner of the manual movement, value stores the style of the bone card to be dragged (one of the four types), so that when you drag the bone card, according to the stored steps (hashmap storage personally think it is very suitable, in addition, the efficiency is also very good, it should be noted that the PUT Method in hashmap is used), determine whether the walk method is correct, and give related tips, there is an automatic demonstration part, robot is used here.

/** <Br/> * board coverage algorithm <br/> * @ Param robot automatically demonstrates the robot <br/> * @ Param tr the horizontal coordinate of the Board position <br/> * @ Param TC checkboard position ordinate <br/> * @ Param Dr special checkboard abscissa <br/> * @ Param DC special checkboard ordinate <br/> * @ Param size checkboard size * size <br/> */<br/> private void chessboard (Robot robot, int TR, int TC, int DR, int DC, int size) {<br/> If (size = 1) {<br/> return; <br/>}< br/> int S = size/2; <br/> // upper left corner <br/> If (Dr <tr + S & DC <TC + S) {<br/> point pleftup = new point (tr + s-1, TC + s-1); <br/> If (autoshow) {<br/> robot. delay (autospeed); <br/> // the location of the dominoes, that is, the source location <br/> int SX = chesspanel. size + 10; <br/> int Sy = 2; <br/> // target location <br/> int DY = pleftup. x * (dominosize/2), dx = pleftup. y * (dominosize/2); <br/> // the straight line slope from the source location to the target location <br/> double k = (double) (dy-sy) /(double) (DX-SX); <br/> robot. mousemove (wlocation. X + SX + (dominosize * 3)/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + Sy + (dominosize * 3)/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight); <br/> robot. mousepress (inputevent. button1_mask); <br/> for (INT I = SX; I> DX-1; I-= 2) {<br/> robot. mousemove (wlocation. X + I + (dominosize * 3)/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + (INT) (sy-K * (SX-I) + (dominosize * 3)/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight + 2); <br/>}< br/> robot. delay (autospeed); <br/> robot. mouserelease (inputevent. button1_mask); <br/>}else {<br/> movemethod. put (pleftup, dominopanel. styles [0]); <br/>}< br/> chessboard (robot, TR, TC, Dr, DC, S); <br/> chessboard (robot, TR, TC + S, tr + s-1, TC + S, S); <br/> chessboard (robot, tr + S, TC, tr + S, TC + s-1, S); <br/> chessboard (robot, tr + S, TC + S, tr + S, TC + S, S ); <br/>}< br/> // upper right corner <br/> If (Dr <tr + S & DC> = TC + S) {<br/> point prightup = new point (tr + s-1, TC + s-1); <br/> If (autoshow) {<br/> robot. delay (autospeed); <br/> // the location of the dominoes, that is, the source location <br/> int SX = chesspanel. size + 10; <br/> int Sy = dominosize + 4; <br/> // target location <br/> int DY = prightup. x * (dominosize/2), dx = prightup. y * (dominosize/2); <br/> // the straight line slope from the source location to the target location <br/> double k = (double) (dy-sy) /(double) (DX-SX); <br/> robot. mousemove (wlocation. X + SX + dominosize/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + Sy + (dominosize * 3)/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight); <br/> robot. mousepress (inputevent. button1_mask); <br/> for (INT I = SX; I> DX-1; I-= 2) {<br/> robot. mousemove (wlocation. X + I + dominosize/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + (INT) (sy-K * (SX-I) + (dominosize * 3)/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight + 2); <br/>}< br/> robot. delay (autospeed); <br/> robot. mouserelease (inputevent. button1_mask); <br/>}else {<br/> movemethod. put (prightup, dominopanel. styles [1]); <br/>}< br/> chessboard (robot, TR, TC, tr + s-1, TC + s-1, S ); <br/> chessboard (robot, TR, TC + S, Dr, DC, S); <br/> chessboard (robot, tr + S, TC, tr + S, TC + s-1, S); <br/> chessboard (robot, tr + S, TC + S, tr + S, TC + S, S ); <br/>}< br/> // lower left corner <br/> If (Dr> = tr + S & DC <TC + S) {<br/> point pleftdown = new point (tr + s-1, TC + s-1); <br/> If (autoshow) {<br/> robot. delay (autospeed); <br/> // the location of the dominoes, that is, the source location <br/> int SX = chesspanel. size + 10 + dominosize + 2; <br/> int Sy = dominosize + 4; <br/> // target location <br/> int DY = pleftdown. x * (dominosize/2), dx = pleftdown. y * (dominosize/2); <br/> // the straight line slope from the source location to the target location <br/> double k = (double) (dy-sy) /(double) (DX-SX); <br/> robot. mousemove (wlocation. X + SX + (dominosize * 3)/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + Sy + dominosize/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight); <br/> robot. mousepress (inputevent. button1_mask); <br/> for (INT I = SX; I> DX-1; I-= 2) {<br/> robot. mousemove (wlocation. X + I + (dominosize * 3)/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + (INT) (sy-K * (SX-I) + dominosize/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight + 2); <br/>}< br/> robot. delay (autospeed); <br/> robot. mouserelease (inputevent. button1_mask); <br/>}else {<br/> movemethod. put (pleftdown, dominopanel. styles [2]); <br/>}< br/> chessboard (robot, TR, TC, tr + s-1, TC + s-1, S ); <br/> chessboard (robot, TR, TC + S, tr + s-1, TC + S, S); <br/> chessboard (robot, tr + S, TC, Dr, DC, S); <br/> chessboard (robot, tr + S, TC + S, tr + S, TC + S, S ); <br/>}< br/> // lower right corner <br/> If (Dr> = tr + S & DC> = TC + S) {<br/> point prightdown = new point (tr + s-1, TC + s-1); <br/> If (autoshow) {<br/> robot. delay (autospeed); <br/> // the location of the dominoes, that is, the source location <br/> int SX = chesspanel. size + 10 + dominosize + 2; <br/> int Sy = 2; <br/> // target location <br/> int DY = prightdown. x * (dominosize/2), dx = prightdown. y * (dominosize/2); <br/> // the straight line slope from the source location to the target location <br/> double k = (double) (dy-sy) /(double) (DX-SX); <br/> robot. mousemove (wlocation. X + SX + dominosize/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + Sy + dominosize/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight); <br/> robot. mousepress (inputevent. button1_mask); <br/> for (INT I = SX; I> DX-1; I-= 2) {<br/> robot. mousemove (wlocation. X + I + dominosize/4 + chessboardcovergui. insets. left, <br/> wlocation. Y + (INT) (sy-K * (SX-I) + dominosize/4 + chessboardcovergui. insets. top + chessboardcovergui. menubarheight + 2); <br/>}< br/> robot. delay (autospeed); <br/> robot. mouserelease (inputevent. button1_mask); <br/>}else {<br/> movemethod. put (prightdown, dominopanel. styles [3]); <br/>}< br/> chessboard (robot, TR, TC, tr + s-1, TC + s-1, S ); <br/> chessboard (robot, TR, TC + S, tr + s-1, TC + S, S); <br/> chessboard (robot, tr + S, TC, tr + S, TC + s-1, S); <br/> chessboard (robot, tr + S, TC + S, Dr, DC, S ); <br/>}< br/>

 

The algorithm summary is stuck here. If you don't understand it, You can Google it. The following is a timing item. I didn't know if there was any special timing in Java when I wrote it, so I used a sleep to perform this timing. It's very easy, start another thread (to prevent blocking). In this thread, ++ operations are performed in minutes, seconds, and milliseconds. The specific code is very easy.

Import Java. util. concurrent. timeunit; </P> <p>/** <br/> * @ author zxz <br/> */<br/> public class timerthread extends thread {< /P> <p> // defines whether the timer starts or not, the default value is stop <br/> Private Static Boolean start = false; <br/> // defines the minute, second, and millisecond <br/> Private Static string minute = "0 ", second = "0", millisecond = "0"; <br/> private int m = 0, S = 0, MS = 0; </P> <p>/** <br/> * the constructor initializes the object. <br/> */<br/> private timerthread () {<br/> minute = "0"; <br/> second = "0"; <br/> millisecond = "0"; <br/> m = 0; <br/> S = 0; <br/> MS = 0; <br/> chessboardcovergui. getnumlbl (). settext ("00:00:00"); <br/>}</P> <p> Public timerthread (string minute, string second, string millisecond) {<br/> timerthread. minute = minute; <br/> timerthread. second = Second; <br/> timerthread. millisecond = millisecond; <br/>}</P> <p> @ override <br/> Public void run () {<br/> while (start) {<br/> MS = integer. parseint (millisecond); <br/> S = integer. parseint (second); <br/> M = integer. parseint (minute); <br/> MS ++; <br/> If (MS/10 <1) {<br/> // Add 0 in front of a single digit <br/> millisecond = "0" + MS; <br/>} else if (MS = 100) {<br/> // The timer is stopped when the second digit is exceeded in milliseconds. <br/> millisecond = "00"; <br/> S ++; <br/>} else {<br/> // other cases <br/> millisecond = MS + ""; <br/>}< br/> If (S/10 <1) {<br/> // Add 0 to the front of a single digit <br/> second = "0" + S; <br/>} else if (S = 60) {<br/> // if the value exceeds 60, set it to 00 <br/> second = "00"; <br/> M ++; <br/>} else {<br/> // other cases <br/> second = S + ""; <br/>}< br/> If (M/10 <1) {<br/> // Add 0 to the front of a single digit <br/> minute = "0" + m; <br/>} else if (M = 100) {<br/> // if the number of minutes exceeds 2 digits, the timing is stopped. The calculation times out. <br/> Start = false; <br/>} else {<br/> // other cases <br/> minute = m + ""; <br/>}< br/> chessboardcovergui. getnumlbl (). settext (minute + ":" + second + ":" + millisecond); <br/> try {<br/> timeunit. milliseconds. sleep (9); <br/>} catch (interruptedexception IE) {<br/> IE. printstacktrace (); <br/>}</P> <p>/** <br/> * start timing <br/> */<br /> Public static void starttimer () {<br/> Start = true; <br/> New timerthread (). start (); <br/>}</P> <p>/** <br/> * end time <br/> */<br/> Public static void stoptimer () {<br/> Start = false; <br/>}</P> <p> Public static void continuetimer (string minute, string second, string millisecond) {<br/> Start = true; <br/> New timerthread (minute, second, millisecond ). start (); <br/>}</P> <p>/** <br/> * obtain the current time <br/> * @ return time string xx minutes XX seconds XX milliseconds <br/> */<br/> Public static string getcurrenttime () {<br/> return minute + "Minute" + second + "second" + millisecond + "millisecond"; <br/>}< br/>

 

Okay, it's almost the same. I won't talk about the UI part. All of them are Java swing, because they are working now, they are used. net and swing have forgotten about this, so you still need to review it. Haha. The last few images are necessary. Actually, although it is very simple, many details are taken into consideration during writing.


 

Source code: http://download.csdn.net/source/2545075

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.