태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

adb shell screenrecord --time-limit 30 /sdcard/tetris.mp4



Ref : http://www.droid-life.com/2013/11/04/android-4-4-tip-screen-recording-takes-screenshots-to-a-new-level/

Posted by chobocho

2018년 Toy project로 기능 추가가 쉬운(?) 테트리스를 만들어 보기로 했다.


1. 결과물

먼저 기본 기능만 동작하는 테트리스(?)의 동작 화면은 아래와 같다.


[ 다운로드 링크 ]

https://play.google.com/store/apps/details?id=com.chobocho.tetris





2. 설계

먼저 구현을 위하여 아래와 같이 UML을 그렸다.




3. 상세설명

3.1 Block

Tetris는 아래 7가지 Block를 사용한다

그래서 Tetrominos 라는 추상 클래스를 만들고, 모든 블럭은 이 클래스를 상속받아서 만든다

이렇게 하면 추후 다른 모양의 블럭을 추가 하기가 쉽다.

[ Tetroinos.java ]

package com.chobocho.tetris;
import java.util.*;

public abstract class Tetrominos {
protected int x;
protected int y;
protected int r;
protected int w;
protected int h;
protected int type;
protected int numOfBlockType;
protected int[][][] block;


public Tetrominos() {
}

public void rotate() {
r = (r+1) % numOfBlockType;
}

public void preRotate() {
r = (r-1+numOfBlockType) % numOfBlockType;
}

public void moveLeft() {
x--;
}

public void moveRight() {
x++;
}


public void moveDown() {
y++;
}

public void moveUp() {
y--;
}

public int[][] getBlock() {
return null;
}

public int getWidth() {
return w;
}

public int getHeight() {
return h;
}

public int getX() {
return x;
}

public int getY() {
return y;
}

public int getType() { return type; }
}

각각의 블록은 위 클래스를 상속받아서 구현 한다.

x, y : 블럭이 보드에 표시되는 시작 좌표

w, h : 블럭을 나타내는 배열의 크기 (블럭마다 다르다. I의 경우 4x4 지만, ㅁ의 경우 2x2 면 된다)

r : 회전한 값을 나타내기 위해 필요하다

type : 블럭의 색상을 나타내기 위해 사용한다

numOfBlock : 블럭 회전시 나타날 수 있는 모양의 수 이다.

실제 이를 상속받은 I형 블럭의 구현 클래스의 소스를 확인하면 아래와 같다

[ ITetrominos.java ]

package com.chobocho.tetris;
import java.util.*;

public class ITetrominos extends Tetrominos {

public ITetrominos() {
this.block = new int[][][]{
{
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
},
{
{1, 1, 1, 1},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
}
};
numOfBlockType = 2;
x = 3;
y = 0;
r = 0;
w = 4;
h = 4;
type = 1;
}

public int[][] getBlock() {
return block[r];
}
}


3.2 Tetrominos Factory

Tetris 에서 사용하는 블럭을 만들어 주는 Factory class 이다

게임에 사용되는 모든 블럭은 이 클래스를 통하여 생성한다


[ TetrominosFactory.java ]

Factory pattern을 사용하여, Tetrominos 블럭을 생성한다.

package com.chobocho.tetris;
import java.util.*;

public class TetrominosFactory {

public static Tetrominos create() {
switch( (int) (Math.random() * 7)) {
case 0:
return new OTetrominos();
case 1:
return new ITetrominos();
case 2:
return new LTetrominos();
case 3:
return new JTetrominos();
case 4:
return new TTetrominos();
case 5:
return new STetrominos();
case 6:
return new ZTetrominos();
default:
return new ITetrominos();
}
}

private TetrominosFactory() {}
}

3.3 State

본 테트리스 게임은 4가지의 State를 가진다

1) IDLE

2) PLAY

3) PAUSE

4) GAMEOVER


[ Tetris game state chart ]


그래서 State pattern을 적용하였다.

각각의 State는 TetrisGameState를 상속받는 구조로 되어 있고, 실제 게임 동작은 TetrisPlayState에서 이루어 진다.

[ TetrisGameState.java ]

package com.chobocho.tetris;

public abstract class TetrisGameState {
protected ITetris tetris;

public TetrisGameState() {}

public void init() {}

public void rotate() {}

public void moveLeft() {}

public void moveRight() {}

public void moveDown() {}

public void fixCurrentBlock() {}

public void moveBottom() {}

public void updateBlock() {}

public boolean gameOver() {
return false;
}

public void updateBoard() {}

public Tetrominos getCurrentTetrominos() {
return null;
}

public Tetrominos getNextTetrominos() { return null; }

public void update() {
TetrisLog.d("TetrisGameState.update()");
}
}


TetrisPlayState는 TetrisGameState를 상속받으며, 현재 블럭과 다음 블럭의 정보를 가지고 있다.

사용자가 화면을 터치하여 블럭을 움직이거나 회전을 하게 되면 블럭의 정보를 업데이트 하고

보드에 블럭정보를 업데이트 하는 동작을 한다.

블럭을 이동하고 나면 Observer pattern을 이용하여 UI 화면을 갱신한다


[ TetrisPlayState.java ]

package com.chobocho.tetris;

public class TetrisPlayState extends TetrisGameState {
private Tetrominos currentTetrominos;
private Tetrominos nextTetrominos;
private TetrisBoard tetrisBoard;
private int additionalPoint = 1;

public TetrisPlayState(Tetris tetris, TetrisBoard board) {
this.tetris = tetris;
this.tetrisBoard = board;
currentTetrominos = TetrominosFactory.create();
nextTetrominos = TetrominosFactory.create();
}

public void init() {
this.tetrisBoard.init();
currentTetrominos = TetrominosFactory.create();
nextTetrominos = TetrominosFactory.create();
additionalPoint = 1;
}

public void update() {
TetrisLog.d("TetrisPlayState.update()");
tetris.getObserver().updatePlay();
}

public void moveLeft() {
TetrisLog.d("TetrisPlayState.moveLeft()");
currentTetrominos.moveLeft();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveRight();
TetrisLog.d("Not Accept");
} else {
TetrisLog.d("Accept");
}
}

public void moveRight() {
TetrisLog.d("TetrisPlayState.moveRight()");
currentTetrominos.moveRight();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveLeft();
TetrisLog.d("Not Accept");
} else {
TetrisLog.d("Accept");
}
}

public void rotate() {
TetrisLog.d("TetrisPlayState.rotate()");
currentTetrominos.rotate();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.preRotate();
TetrisLog.d("Not Accept");
} else {
TetrisLog.d("Accept");
}
}

public void moveDown() {
TetrisLog.d("TetrisPlayState.moveDown()");
currentTetrominos.moveDown();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveUp();
TetrisLog.d("Can not move down");
fixCurrentBlock();
updateBoard();
updateBlock() ;
} else {
TetrisLog.d("Accept");
}
}

public void moveBottom() {
TetrisLog.d("TetrisPlayState.moveBottom()");
while(tetrisBoard.isAcceptable(currentTetrominos)) {
currentTetrominos.moveDown();
}
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveUp();
}
}

public void fixCurrentBlock() {
tetrisBoard.addTetrominos(currentTetrominos);
}

public void updateBlock() {
currentTetrominos = nextTetrominos;
nextTetrominos = TetrominosFactory.create();
}

public boolean gameOver() {
TetrisLog.d("Game over!");
return (tetrisBoard.isAcceptable(currentTetrominos) == false);
}

public void updateBoard() {
int removedLine = tetrisBoard.arrange();
int point = calculatorScore(removedLine);
tetris.addSore(point);
}

private int calculatorScore(int removedLineCount) {
if (removedLineCount == 0) {
additionalPoint = 1;
return 0;
}
if (removedLineCount >= 4) {
removedLineCount = 4;
}
if (additionalPoint > 10000) {
additionalPoint = 10000;
}
additionalPoint <<= removedLineCount;
TetrisLog.d("calculatorScore : " + additionalPoint + " : " + removedLineCount);
return (removedLineCount * 10 * additionalPoint);
}

public Tetrominos getCurrentTetrominos() {
return currentTetrominos;
}

public Tetrominos getNextTetrominos() {
return nextTetrominos;
}
}

3.4 Board

3.5 Observer pattern

3.6 Tetris


3.7 Source 코드로 부터 생성한 UML







4. Source code

https://github.com/chobocho/ClassBlockGame


5. Reference

* Head first design pattern


* 질문은 언제나 환영 합니다.

Posted by chobocho

Rename

Coding/Python 삽질기 2017.11.24 00:28
import os

'''
Start : 2017.11.23
End : 2017.11.23
'''

currdir = os.getcwd()
fileList = []

fileList = os.listdir(currdir)

for filename in fileList:
fullfilename = os.path.join(currdir, filename)

if os.path.isdir(fullfilename):
print "["+fullfilename+ "]"
elif (".gif" in fullfilename) and ("_" not in fullfilename):
newFileName = fullfilename[:-4] + "_1.gif"
os.rename(fullfilename, newFileName)
print fullfilename + " -> " + newFileName


'Coding > Python 삽질기' 카테고리의 다른 글

Python Tip  (0) 2018.04.26
Rename  (0) 2017.11.24
Python으로 만든 File manager  (0) 2017.08.20
[Python] 날짜 시간 출력 하기  (0) 2017.07.08
Posted by chobocho
TAG Python
1. sdkman 설치

curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh”

2. Java와 Kotlin 설치 
sdk install java
sdk install kotlin

3. Kotlin 으로 helloworld.kt  만들기

fun main(args: Array<String>) { 
    println("Hello, World!!”)
}


4. Compile helloworld.kt
kotlinc helloworld.kt -include-runtime -d helloworld.jar

5. 실행하기
java -jar helloworld.jar

* Reference

http://sdkman.io/install.html

https://kotlinlang.org/docs/tutorials/command-line.html



'Coding > JVM 삽질기' 카테고리의 다른 글

Mac에서 Kotlin 설치하기  (0) 2017.10.14
[groovy] 50!  (0) 2016.09.24
Groovy 설치( Mac )  (0) 2014.11.11
Pocket PC를 위한 JVM  (0) 2005.09.28
Posted by chobocho
TAG kotlin


1) Menu > 확장 프로그램 > Evernote Web Clipper 제거
2) '확장 프로그램 더보기’ 클릭 > Evernote Web Clipper 설치


'Coding > Evernote' 카테고리의 다른 글

Safari web clipper 가 동작을 하지 않을 때  (0) 2017.10.07
[Evernote 활용] 바코드 모으기  (0) 2017.04.30
Evernote Atlas 기능  (0) 2014.11.20
Posted by chobocho

 

2017.08.23a

2017.08.22.b

2017.08.22

2017.08.20

 

https://github.com/chobocho/chobofilemanager

'Coding > Python 삽질기' 카테고리의 다른 글

Rename  (0) 2017.11.24
Python으로 만든 File manager  (0) 2017.08.20
[Python] 날짜 시간 출력 하기  (0) 2017.07.08
[Python] Sleep  (0) 2017.07.08
Posted by chobocho

https://notepad-plus-plus.org/

 

개인적으로 생각하는 최고의 무료 에디터 이다.

 

 


 

https://code.visualstudio.com/

https://github.com/Microsoft/vscode

 

요즘 즐겨 사용하는 에디터

 

 

'Coding > 좋은 사이트' 카테고리의 다른 글

함수의 그래프를 그려주는 사이트  (0) 2018.03.03
무료 에디터  (1) 2017.07.27
[UML] Plantuml  (0) 2016.12.27
추천 사이트 모음  (4) 2010.03.16
Posted by chobocho

[ Using a sparse-checkout to clone speical folder only ]




mkdir paperjs

cd paperjs

git init


git remote add origin https://github.com/paperjs/paperjs.github.io.git

git config core.sparsecheckout true

echo "examples/*" >> .git/info/sparse-checkout

# Tip!!

# Windows power shell에서는 하기와 같이 하여야 함

# 그렇지 않으면

# error: Sparse checkout leaves no entry on the working directory 에러 메시지가 보임

# echo "examples/*"| out-file -encoding ascii .git/info/sparse-checkout

#

git pull --depth=2 origin master




* 참고 사이트 : https://stackoverflow.com/questions/23289006/on-windows-git-error-sparse-checkout-leaves-no-entry-on-the-working-directory

Posted by chobocho

#include <iostream>

using namespace std;


class CPoint {

public:

void set(int a_, int b_) { a = a_; b = b_; }

bool small(const CPoint &p) {

unsigned long long int la = b;

unsigned long long int lb = p.a;

unsigned long long int lb2 = p.b;

unsigned long long int l = la * lb + lb2;

la = p.b;

lb = a;

lb2 = b;

unsigned long long int r = la * lb + lb2;

return l < r;

}

bool big(const CPoint &p) {

unsigned long long int la = b;

unsigned long long int lb = p.a;

unsigned long long int lb2 = p.b;

unsigned long long int l = la * lb + lb2;

la = p.b;

lb = a;

lb2 = b;

unsigned long long int r = la * lb + lb2;

return l > r;

}

int a, b;

};



void qsort(CPoint* arr, int start, int end) {

CPoint p = arr[(start + end) / 2];

int s = start;

int e = end;


while (s <= e) {

while (arr[s].small(p)) { s++; }

while (arr[e].big(p)) { e--; }

if (s <= e) {

CPoint t = arr[s];

arr[s] = arr[e];

arr[e] = t;

s++;

e--;

}

}


if (start < e) {

qsort(arr, start, e);

}

if (s < end) {

qsort(arr, s, end);

}

}


CPoint p[200001];


int main()

{

int TC = 0;

cin >> TC;


for (int tc = 1; tc <= TC; tc++) {

int N = 0;

cin >> N;

for (int i = 0; i < N; i++) {

cin >> p[i].a >> p[i].b;

}

qsort(p, 0, N - 1);

cout << "# " << tc << " " << N <<  endl;

for (int i = 0; i < N; i++) {

cout << p[i].a << " " << p[i].b << endl;

}

}


    return 0;

}



'Coding > C/CPP 삽질기' 카테고리의 다른 글

Quick sort  (0) 2017.07.13
Bit 연산 정리  (0) 2016.08.20
가장 넓은 직사각형 구하는 알고리즘 ( O(MN) )  (0) 2016.04.13
printf로 디버깅 하기  (0) 2016.04.13
Posted by chobocho

날짜 시간 출력 하기



  1. 날짜 시간 출력 하기



import datetime


today = datetime.datetime.now()

print today

print today.strftime("%Y.%m.%d")

print today.strftime("%Y.%m.%d %H:%M:%S")



2017-07-08 01:07:53.874000

2017.07.08

2017.07.08 01:07:53



'Coding > Python 삽질기' 카테고리의 다른 글

Python으로 만든 File manager  (0) 2017.08.20
[Python] 날짜 시간 출력 하기  (0) 2017.07.08
[Python] Sleep  (0) 2017.07.08
[Python] Thread example  (0) 2017.06.30
Posted by chobocho