殘缺棋盤 android實現顏色填充

許佳佳233發表於2016-05-17

原“殘缺棋盤”題目:


殘缺棋盤是一個2^k*2^個方格的棋盤,其中恰有1個方格殘缺。圖中給出,其中殘缺部分用陰影表示。


這樣的棋盤稱為"三格板",殘缺棋盤問題就是用這四種三格板覆蓋更大的殘缺棋盤。再次覆蓋中要求:

(1)兩個三格板不能重複。

(2)三格板不能覆蓋殘缺棋盤方格,但必須覆蓋到其他所有的方格。


新增要求:

1、使用圖形化介面實現顏色填充殘缺棋盤

2、填充的色塊,相鄰之間的顏色不能相同


最終效果:(原始碼在文章結尾)



演算法可以參考部落格:

http://blog.csdn.net/gzj_1101/article/details/49368143


android介面實現:

1、方格的view用gridview實現,item中放50px*50px的view。

2、考慮到可能會超出螢幕用HorizontalScrollView包裹gridview。

3、新建一個mColor的int[][]的二維陣列儲存每個view的背景顏色,在執行演算法時候改變背景顏色。

執行完畢,更新gridview的adapter。



碰到的問題:

HorizontalScrollView與gridview衝突,寬度上無法正常顯示。


解決辦法:(原理可以參考筆者部落格:http://blog.csdn.net/double2hao/article/details/51438798

使用一個LinearLayout包裹gridview,然後讓HorizontalScrollView包裹LinearLayout。

gridview繫結了adapter之後,設定LinearLayout的寬度就可以了。


如下圖:







MainActivity:

package com.example.double2.gridviewtest;

import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private GridView mGridView;
    private int mSize = 1;
    private int mY;
    private int mX;
    final int[] twoColor = {Color.GREEN, Color.YELLOW};
    int colorIndex = 0;//顏色的下標,0的時候表示綠色,1的時候表示黃色
    int colorItem = 1;//填充顏色的時候,一個顏色填兩次,然後換一個顏色,colorItem用來記錄填充次數
    private int[][] mColor;
    private EditText etSize;
    private EditText etY;
    private EditText etX;
    private Button btnCreate;
    private Button btnStart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        mGridView = (GridView) findViewById(R.id.gv_main);
        etSize = (EditText) findViewById(R.id.et_main_size);
        etY = (EditText) findViewById(R.id.et_main_y);
        etX = (EditText) findViewById(R.id.et_main_x);
        btnCreate = (Button) findViewById(R.id.btn_main_create);
        btnStart = (Button) findViewById(R.id.et_main_start);

        btnCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int k = Integer.parseInt(etSize.getText().toString());
                mSize = (int) Math.pow(2, k);//獲取到mSize

                mGridView.setNumColumns(mSize);
                mGridView.setAdapter(new GridViewAdapter(MainActivity.this));
                setGridViewWidth(mGridView);
                mColor = new int[mSize][mSize];
                for (int i = 0; i < mSize; i++) {
                    for (int j = 0; j < mSize; j++)
                        mColor[i][j] = Color.WHITE;
                }

                //重置棋盤的一些資訊
                colorIndex = 0;
                colorItem = 1;
            }
        });

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //添上try catch,防止X和Y的EditText值為空的情況
                try {
                    mY = Integer.parseInt(etY.getText().toString());
                    mX = Integer.parseInt(etX.getText().toString());
                } catch (Exception e) {
                }
                if (mSize == 1) {
                    Toast.makeText(MainActivity.this, "請先建立檢視!", Toast.LENGTH_SHORT).show();
                } else if (etY.getText().toString().equals("") || etX.getText().toString().equals("")) {
                    Toast.makeText(MainActivity.this, "請輸入X和Y的值!", Toast.LENGTH_SHORT).show();
                } else if (mY >= mSize || mX >= mSize) {
                    Toast.makeText(MainActivity.this, "X或Y的值越界!", Toast.LENGTH_SHORT).show();
                } else {
                    //考慮到可能多次計算同一個size的情況,要讓第一個殘缺的位置為白色
                    mColor[mX][mY] = Color.WHITE;
                    //使用AsyncTask線上程中計算
                    new Caculation().execute();
                }
            }
        });
    }

    public class Caculation extends AsyncTask<Void, Void, Void> {


        @Override
        protected Void doInBackground(Void... params) {
            //線上程中進行三角板的遞迴
            cover(0, 0, mX, mY, mSize);
            return null;
        }


        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            //在計算結束之後重新整理gridView的adapter
            mGridView.setAdapter(new GridViewAdapter(MainActivity.this));
            setGridViewWidth(mGridView);
        }

        void cover(int tr, int tc, int dr, int dc, int size) {
            int s;
            s = size / 2;

            if (size == 2) {
                if (dr < tr + s && dc < tc + s) {
                    mColor[tr + s - 1][tc + s] = twoColor[colorIndex];
                    mColor[tr + s][tc + s - 1] = twoColor[colorIndex];
                    mColor[tr + s][tc + s] = twoColor[colorIndex];
                } else if (dr < tr + s && dc >= tc + s) {
                    mColor[tr + s - 1][tc + s - 1] = twoColor[colorIndex];
                    mColor[tr + s][tc + s - 1] = twoColor[colorIndex];
                    mColor[tr + s][tc + s] = twoColor[colorIndex];
                } else if (dr >= tr + s && dc < tc + s) {
                    mColor[tr + s - 1][tc + s - 1] = twoColor[colorIndex];
                    mColor[tr + s - 1][tc + s] = twoColor[colorIndex];
                    mColor[tr + s][tc + s] = twoColor[colorIndex];
                } else if (dr >= tr + s && dc >= tc + s) {
                    mColor[tr + s - 1][tc + s - 1] = twoColor[colorIndex];
                    mColor[tr + s - 1][tc + s] = twoColor[colorIndex];
                    mColor[tr + s][tc + s - 1] = twoColor[colorIndex];
                }
                if (colorItem == 1) {
                    colorItem = 0;
                    if (colorIndex == 1)
                        colorIndex = 0;
                    else
                        colorIndex = 1;
                } else {
                    colorItem++;
                }
            } else {
                if (dr < tr + s && dc < tc + s) {           //左上
                    mColor[tr + s - 1][tc + s] = Color.RED;
                    mColor[tr + s][tc + s - 1] = Color.RED;
                    mColor[tr + s][tc + s] = Color.RED;
                    cover(tr, tc, dr, dc, s);
                    cover(tr, tc + s, tr + s - 1, tc + s, s);
                    cover(tr + s, tc, tr + s, tc + s - 1, s);
                    cover(tr + s, tc + s, tr + s, tc + s, s);
                } else if (dr < tr + s && dc >= tc + s) {       //右上
                    mColor[tr + s - 1][tc + s - 1] = Color.RED;
                    mColor[tr + s][tc + s - 1] = Color.RED;
                    mColor[tr + s][tc + s] = Color.RED;
                    cover(tr, tc, tr + s - 1, tc + s - 1, s);
                    cover(tr, tc + s, dr, dc, s);
                    cover(tr + s, tc, tr + s, tc + s - 1, s);
                    cover(tr + s, tc + s, tr + s, tc + s, s);
                } else if (dr >= tr + s && dc < tc + s) {       //左下
                    mColor[tr + s - 1][tc + s - 1] = Color.RED;
                    mColor[tr + s - 1][tc + s] = Color.RED;
                    mColor[tr + s][tc + s] = Color.RED;
                    cover(tr, tc, tr + s - 1, tc + s - 1, s);
                    cover(tr, tc + s, tr + s - 1, tc + s, s);
                    cover(tr + s, tc, dr, dc, s);
                    cover(tr + s, tc + s, tr + s, tc + s, s);
                } else if (dr >= tr + s && dc >= tc + s) {      //右上
                    mColor[tr + s - 1][tc + s - 1] = Color.RED;
                    mColor[tr + s - 1][tc + s] = Color.RED;
                    mColor[tr + s][tc + s - 1] = Color.RED;
                    cover(tr, tc, tr + s - 1, tc + s - 1, s);
                    cover(tr, tc + s, tr + s - 1, tc + s, s);
                    cover(tr + s, tc, tr + s, tc + s - 1, s);
                    cover(tr + s, tc + s, dr, dc, s);
                }
            }
        }
    }

    private class GridViewAdapter extends BaseAdapter {

        private Context context;

        public GridViewAdapter(Context context) {
            this.context = context;
        }

        int count = mSize * mSize;

        @Override
        public int getCount() {
            return count;
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View result = new View(context);
            //設定固定寬高50px
            result.setLayoutParams(new AbsListView.LayoutParams(50, 50));
            result.setBackgroundColor(mColor[position / mSize][position % mSize]); //設定背景顏色
            return result;
        }

    }

    public void setGridViewWidth(GridView gView) {
        //由於HorizontalScrollView和GridView共同使用的時候寬度上會有問題
        //所以此處重置GridView的寬度來解決這個問題
        //56=50+6,單位為px,50為view的寬度,6為預留的子部局間隔
        gView.setLayoutParams((new LinearLayout.LayoutParams(56 * mSize, ViewGroup.LayoutParams.WRAP_CONTENT)));
    }
}

activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="請輸入2^k中k的值:"
            android:textColor="#000"
            android:textSize="20sp"/>

        <EditText
            android:id="@+id/et_main_size"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:digits="123456"
            android:hint="請輸入1~6的數"
            android:maxLength="1"
            />
    </LinearLayout>

    <Button
        android:id="@+id/btn_main_create"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="創 建 視 圖"
        android:textSize="20sp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="請輸入初始點的位置"
            android:textColor="#000"
            android:textSize="20sp"/>

        <EditText
            android:id="@+id/et_main_x"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:digits="0123456789"
            android:hint="x=?"/>

        <EditText
            android:id="@+id/et_main_y"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:digits="0123456789"
            android:hint="y=?"/>
    </LinearLayout>

    <Button
        android:id="@+id/et_main_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="開 始 運 行"
        android:textSize="20sp"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="結果如下:"
        android:textSize="20sp"/>

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <GridView
                android:id="@+id/gv_main"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#DCDCDC"
                android:horizontalSpacing="4dp"
                android:padding="5dp"
                android:verticalSpacing="4dp"
                />
        </LinearLayout>
    </HorizontalScrollView>
</LinearLayout>


原始碼地址:http://download.csdn.net/detail/double2hao/9523250

相關文章