어릴때 많이 가지고 놀던 숫자 퍼즐게임인데...

인터넷 돌아다니다 우현히 보게되서...

어떻게 만들었을까 고민 시작 하기도 전에 코딩해봤습니다...

 

안드로이드에서 기본 제공하는 버튼과 기본 레이아웃을 사용. 소스는 아래와 같습니다.

 

gradientbox3.xml (버튼 그라디언트 주기위해)

 

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
   
    <corners android:radius="20dp"/>
   
    <gradient
        android:startColor="#FFAAAAFF"
        android:endColor="#FFffffff"
        android:angle="90" />
   
    <padding
     android:left="5dp"
     android:top="5dp"
     android:right="5dp"
     android:bottom="5dp" />
   
    <stroke
        android:width="4dp"
        android:color="#99232323" />
   
</shape>

다음은 기본으로 생성되는 엑티비디에 전체 소스를 쑤셔 넣었어요.......

 

package com.example.mygame001;

import java.util.Random;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {
 
 private int[][] cellData;
 private int BtnWidth;
 private RelativeLayout cv;
 private Button startBtn;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  super.onCreate(savedInstanceState);
  
  RelativeLayout gameView = new RelativeLayout(this);
  setContentView(gameView);
  
  cv = new RelativeLayout(this);
  cv.setBackgroundColor(Color.argb(180, 0, 0, 0));
  gameView.addView(cv);
  
  int sw = getWindow().getWindowManager().getDefaultDisplay().getWidth();
  int nb = 3;
  BtnWidth = sw / nb;
  int indexBtn = 0;
  
  cellData = new int[nb][nb];
  
  Button mb = null;
  RelativeLayout.LayoutParams lp = null;
  for(int ny=0; ny<nb; ny++){
   for(int nx=0; nx<nb; nx++){
    mb = new Button(this);
    lp = new RelativeLayout.LayoutParams(BtnWidth,BtnWidth);
    lp.leftMargin = nx * BtnWidth;
    lp.topMargin = ny * BtnWidth;
    mb.setLayoutParams(lp);
    mb.setBackgroundResource(R.drawable.gradientbox3);
    mb.setTextSize(72);
    mb.setText(String.valueOf(++indexBtn));
    mb.setOnClickListener(BtnClick);
    cv.addView(mb);
    cellData[ny][nx] = 1;
   }
  }
  cv.removeViewAt(nb*nb-1);
  cellData[nb-1][nb-1] = 0;
  
  startBtn = new Button(this);
  lp = new RelativeLayout.LayoutParams(sw, 120);
  lp.topMargin = BtnWidth * nb;
  startBtn.setLayoutParams(lp);
  startBtn.setTextSize(32);
  startBtn.setText("START GAME");
  startBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    shufflePosition();
   }
  });
  gameView.addView(startBtn);
 }
 private View.OnClickListener BtnClick = new View.OnClickListener() {
  @Override
  public void onClick(View v) {
   moveButton(v, getEmptyCell(v));
   if( isCompleteGame() && timeCount != 0){
    startBtn.setText("COMPLETE GAME "+String.valueOf(timeCount));
   }
   int nb=3;
   Log.d("++GAME","--------------------");
   for(int ny=0; ny<nb; ny++){
     Log.d("++GAME", String.valueOf(cellData[ny][0])+","+String.valueOf(cellData[ny][1])+","+String.valueOf(cellData[ny][2]));
   }
  }
 };
 private int getEmptyCell(View v){
  RelativeLayout.LayoutParams rp = (RelativeLayout.LayoutParams)v.getLayoutParams();
  int ny = Integer.valueOf(rp.topMargin / BtnWidth);
  int nx = Integer.valueOf(rp.leftMargin / BtnWidth);
  int result =  (nx-1>=0 && cellData[ny][nx-1] == 0)? 1:
       (nx+1<=2 && cellData[ny][nx+1] == 0)? 2:
       (ny-1>=0 && cellData[ny-1][nx] == 0)? 3:
       (ny+1<= 2 && cellData[ny+1][nx] == 0)? 4:0;
  return result;
 }
 private void moveButton(View v, int dir){
  RelativeLayout.LayoutParams rp = (RelativeLayout.LayoutParams)v.getLayoutParams();
  int ny = Integer.valueOf(rp.topMargin / BtnWidth);
  int nx = Integer.valueOf(rp.leftMargin / BtnWidth);
  switch(dir){
  case 1: rp.leftMargin -= BtnWidth; cellData[ny][nx] = 0; cellData[ny][nx-1] = 1;break;
  case 2: rp.leftMargin += BtnWidth; cellData[ny][nx] = 0; cellData[ny][nx+1] = 1;break;
  case 3: rp.topMargin -= BtnWidth; cellData[ny][nx] = 0; cellData[ny-1][nx] = 1;break;
  case 4: rp.topMargin += BtnWidth; cellData[ny][nx] = 0; cellData[ny+1][nx] = 1;break;
  }
  v.setLayoutParams(rp);
 }
 private boolean isCompleteGame(){
  boolean result = true;
  for(int i=cv.getChildCount()-1; i>0; i--){
   Button btn = (Button)cv.getChildAt(i);
   RelativeLayout.LayoutParams rp = (RelativeLayout.LayoutParams)btn.getLayoutParams();
   int ny = Integer.valueOf(rp.topMargin / BtnWidth);
   int nx = Integer.valueOf(rp.leftMargin / BtnWidth);
   int id = Integer.valueOf(btn.getText().toString());
   if(
     (ny==0 && nx+1==id) ||
     (ny==1 && nx+4==id) ||
     (ny==2 && nx+7==id)
   ){}else{
    result = false;
    break;
   }
  }
  return result;
 }
 private void shufflePosition(){
  Random rnd = new Random();
  for(int i=cv.getChildCount()-1; i>0; i--){
   int index = rnd.nextInt(i+1);
   RelativeLayout.LayoutParams first = (RelativeLayout.LayoutParams)((Button)cv.getChildAt(index)).getLayoutParams();
   RelativeLayout.LayoutParams next = (RelativeLayout.LayoutParams)((Button)cv.getChildAt(i)).getLayoutParams();
   ((Button)cv.getChildAt(index)).setLayoutParams(next);
   ((Button)cv.getChildAt(i)).setLayoutParams(first);
  }
  timeCount = 0;
  if(handler==null){
   handler = new Handler();
   checkTime();
  }
 }
 private void shuffleLable(){
  Random rnd = new Random();
  for(int i=cv.getChildCount()-1; i>0; i--){
   int index = rnd.nextInt(i+1);
   String lbl = ((Button)cv.getChildAt(index)).getText().toString();
   String tmp = ((Button)cv.getChildAt(i)).getText().toString();
   ((Button)cv.getChildAt(index)).setText(tmp);
   ((Button)cv.getChildAt(i)).setText(lbl);
  }
 }
 private int timeCount=0;
 Handler handler;
 private void checkTime(){
        handler.postDelayed(new Runnable(){
          public void run(){
           timeCount++;
           checkTime();
           if(timeCount<60){
            startBtn.setText(String.valueOf(timeCount)+" 초 경과.");
           }else{
            int m = timeCount/60;
            int s = timeCount-(m*60);
            startBtn.setText(String.valueOf(m)+"분 "+String.valueOf(s)+"초 경과.");
           }
          }
        }, 1000); 
 }

}

위소스를 실행한 화면은 아래와 같습니다...

 

Screenshot_2013-11-14-23-18-30.png

 

기획도 없고, 설계도 없고, 머리에 그려지는 대로 코딩해서, 주석도 없습니다.