An Algorithm for searching board groups in flood-It games

Source: Internet
Author: User

Author: Xu Jin

This article is based on the knowledge and courseware taught by our AI instructor Xu in the class, which is further embodied in the results after code.

Some images in this article are from the instructor's courseware.

Flood-It games
Game Board:

Game rules:

From the top left of the square, change all the squares to the same color.
The following operations are performed repeatedly to change the color of the same color block that is connected to the leftmost square to the color of the horizontal or vertical adjacent square.

Example:

Data Representation:

The data representation of this game consists of two parts: Color encoding, six colors, 0 ~ 5. To simplify the searchConnected color blocksInto a group.

For example:

How can we implement this grouping method?

Below is my algorithm:

Declaration: here, the color block uses 0 ~ 24 indicates that the group uses 1 ~ N, which is different from the figure above. Please note !!

First, you must randomly generate an initial state, and then generate an initial state according to the color block (for example, the color block is 0 ~ 24) color recognition group (for example, the group is 1 ~ 17 ).

I created a function called judgegroup (node) to identify a group. This function accepts a Node object (only the color is correct, but the group is not recognized) and returns the Node object that has been recognized by the Group.


Judgegroup (node) Function

First, let's take a look at the judgegroup (node) function:

// Identify the group. The color has been changed but the group is messy. Change the group according to the color here. public static node judgegroup (node nextnode) {// pre-processing int [] [] status = new int [width * width] [3]; // status [I] [0] indicates the group, status [I] [1] indicates the color, status [I] [2] indicates whether the group is determined, and 0 indicates that the group is not determined, 1. If the group is 1, the Group for (INT I = 0; I <width * width; I ++) is determined) {status [I] [0] = nextnode. status [I] [0]; status [I] [1] = nextnode. status [I] [1]; status [I] [2] = 0;} // search for int num = 1 in the following iteration; For (INT I = 0; I <width * width; I ++) {If (status [I] [2] = 0) {status [I] [0] = num ++; status = searchgroup (status, I) ;}return new node (Status );}

This function has an important variable, status [] [] array, which has 25 numbers in the first dimension, indicating the number of the Color Block, from 0 ~ 24 (when width is 5), and the second-dimension has three numbers, indicating 0: The color block group, 1: The color block, 2: whether the color block group is correct (0 indicates incorrect, 1 indicates correct, and the default value is incorrect ).

After simple preprocessing, you can search. My search algorithm is one by one based on the color block numbers. If the color block group is incorrect, the searchgroup function is called.

Searchgroup Function

The searchgroup function accepts a status array and the number I of a color block, and returns an array of status that has been identified. This function first checks 0th color blocks and finds that the group is incorrect (status [I] [3] = 0). It checks both the top, bottom, and left sides, if a color block with the same color is found, such as (I + 1), use the searchgroup function to search for the I + 1 color block. In this way, the array of status variables returned to judgegroup is the status array that recognizes all the first color blocks. Then, check the 1st color blocks and determine whether to call the searchgroup function based on the value of status [I] [3.

public static int[][] searchGroup(int[][] status, int i){//upif(i / WIDTH != 0 && status[i - WIDTH][2] == 0){if(status[i][1] == status[i - WIDTH][1]){status[i - WIDTH][0] = status[i][0];status[i - WIDTH][2] = 1;status = searchGroup(status, i - WIDTH);}}//downif(i / WIDTH != WIDTH - 1 && status[i + WIDTH][2] == 0){if(status[i][1] == status[i + WIDTH][1]){status[i + WIDTH][0] = status[i][0];status[i + WIDTH][2] = 1;status = searchGroup(status, i + WIDTH);}}//leftif(i % WIDTH != 0 && status[i - 1][2] == 0){if(status[i][1] == status[i - 1][1]){status[i - 1][0] = status[i][0];status[i - 1][2] = 1;status = searchGroup(status, i - 1);}}//rightif(i % WIDTH != WIDTH - 1 && status[i + 1][2] == 0){if(status[i][1] == status[i + 1][1]){status[i + 1][0] = status[i][0];status[i + 1][2] = 1;status = searchGroup(status, i + 1);}}return status;}

The above is only a search algorithm for groups in the initial state, and searching for groups in the game is easier than the above method, the reason is that during the game, you only need to search which color blocks are included in the first group with the same color as the top left corner, and others do not need to be searched (because the initial status has already been searched, re-search is repetitive work ).

Finally, I will give a rough program. The program will first output a random Checker with a group, asking the user to enter a number representing the color. After the user inputs it, the system will change the color again, and update the group.

The following is a compilation and running source program that realizes group recognition:

Package COM. xujin; import Java. util. random; import Java. util. vertex;/** game: Flood it * Author: Xu Jin * Date: 2013/4/10 * only indicates the data structure, block search **/public class flooditgame {public static void main (string... ARGs) {flooditgame newgame = new flooditgame (); startstatus = newgame. randomstatus (); system. out. println (startstatus); // newgame. process (startstatus); currentstatus = new node (startstatus. status); current Status. Groups [1] = 1; system. Out. println ("enter the next color (0 ~ 5): "); // The game starts while (CIN. hasnext () {int nextcolor = cin. nextint (); currentstatus = changecolor (currentstatus, nextcolor); If (found (currentstatus) {system. out. println ("You win !!! "); Break;} system. out. println (currentstatus); For (INT I = 0; I <width * width; I ++) if (currentstatus. groups [I] = 1) system. out. print (I + 1) + ""); system. out. println () ;}}// generate a Random Initial State Public node randomstatus () {int [] [] status = new int [width * width] [2]; random random = new random (); // first generates the color for (INT I = 0; I <width * width; I ++) status [I] [1] = random. nextint (6); node startstatus = new node (Status); // then identify Startstatus. groups [0] = 1; // at first, only one color block in the upper left corner belongs to the first group, and also belongs to the return judgegroup (startstatus);} // recognition group, the color has been changed before, but the group is messy. Here, the group is changed based on the color. public static node judgegroup (node nextnode) {// pre-processing int [] [] status = new int [width * width] [3]; // status [I] [0] indicates the group, status [I] [1] indicates the color, status [I] [2] indicates whether the group is determined, and 0 indicates that the group is not determined, 1. If the group is 1, the Group for (INT I = 0; I <width * width; I ++) is determined) {status [I] [0] = nextnode. status [I] [0]; status [I] [1] = nextnode. Status [I] [1]; status [I] [2] = 0;} // search for int num = 1 in the following iteration; For (INT I = 0; I <width * width; I ++) {If (status [I] [2] = 0) {status [I] [0] = num ++; status = searchgroup (status, I) ;}return new node (Status) ;}public static int [] [] searchgroup (INT [] [] status, int I) {// upif (I/width! = 0 & status [I-width] [2] = 0) {If (status [I] [1] = status [I-width] [1]) {status [I-width] [0] = status [I] [0]; status [I-width] [2] = 1; status = searchgroup (status, i-width) ;}// downif (I/width! = Width-1 & status [I + width] [2] = 0) {If (status [I] [1] = status [I + width] [1]) {status [I + width] [0] = status [I] [0]; status [I + width] [2] = 1; status = searchgroup (status, I + width) ;}// leftif (I % width! = 0 & status [I-1] [2] = 0) {If (status [I] [1] = status [I-1] [1]) {status [I-1] [0] = status [I] [0]; status [I-1] [2] = 1; status = searchgroup (status, i-1) ;}// rightif (I % width! = Width-1 & status [I + 1] [2] = 0) {If (status [I] [1] = status [I + 1] [1]) {status [I + 1] [0] = status [I] [0]; status [I + 1] [2] = 1; status = searchgroup (status, I + 1) ;}} return status ;}// assume that the color changed must be different from the previous one. Change the color and update the group, public static node changecolor (node, int nextcolor) {int nextstatus [] [] = new int [width * width] [2]; for (INT I = 0; I <width * width; I ++) {If (node. status [I] [0] = 1) {// if the group is 1 nextstatus [I] [1] = nextcolor ;//!~ Bug ~~!!!!} Else {nextstatus [I] [1] = node. status [I] [1];} nextstatus [I] [0] = node. status [I] [0];} node nextnode = new node (nextstatus); For (INT I = 0; I <width * width; I ++) nextnode. groups [I] = node. groups [I]; nextnode. steps = node. steps + 1;/****** simplified judgegroup, only process the first block ************************************ * *** // pre-process int [] [] status = new int [width * width] [3]; // status [I] [0] indicates the group, status [I] [1] indicates the color, status [I] [2] indicates whether the group is determined, 0 Not determined, 1 is determined; as long as the group is 1, the group is determined for (INT I = 0; I <width * width; I ++) {status [I] [0] = nextnode. status [I] [0]; status [I] [1] = nextnode. status [I] [1]; status [I] [2] = 0;} status = searchgroup (status, 0); nextnode. status = status;/****** simplified judgegroup, only process the first block ************************************ * *** // compare the groups in the first block for (INT I = 0; I <width * width; I ++) {If (nextnode. status [I] [0] = 1) nextnode. groups [startstatus. stat Us [I] [0]-1] = 1;} return nextnode;} public static Boolean found (node) {for (INT I = 1; I <width * width; I ++) {If (node. status [I] [0]! = 1) return false;} return true;} public static variable CIN = new variable (system. in); Private Static node startstatus; Private Static node currentstatus; public static final int width = 5; // Private Static string result = ""; // record the result, for example: blue, red, green ...... // Private queue <node> open = new queue list <node> (); // Private queue <node> open = new priorityqueue <node> (); // Private hashset <node> close = new hashset <node> ();} c Lass node {public node (INT [] [] Status) {This. status = status ;}@ overridepublic string tostring () {string currentstatus = ""; for (INT I = 0; I <width * width; I ++) {currentstatus + = status [I] [0] + "/" + status [I] [1] + ""; if (I % 5 = 4) currentstatus + = "\ n";} return currentstatus;} public int [] [] status = new int [width * width] [3]; // I represents 0 ~ 24 location, status [I] [0] group, status [I] [1] color, status [I] [2] indicates whether the Group Public int steps = 0 is determined; int [] groups = new int [width * width]; // stores whether a group is included in the first block, with the subscript 0 ~ 24 represents 1 ~ 25 groups of public static final int width = 5; Public node pernode; Public int percolor ;}

Copyright: Xu Jin

Blog: http://blog.csdn.net/xujinsmile

Thank you.

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.