Java Intermediate

Java Intermediate

written by sean base on following books
_images/chapter0_4.png _images/chapter0_3.png

Github | https://github.com/newsteinking/High_pythondocminecraft

Chapter 0: About

Python minecraft Curriculm

by sean

Base on Python : Learn to Program with Minecraft

_images/chapter0_1.png

Thanks to

잠시나마 오픈소스에 대한 희망을 안겨주었던 멤버들에게 감사의 마음을 전합니다. 다들 다른곳에서 각자 열심히 일하는데 모두들 건승하길 바랍니다.
  • sean
  • Mr Ju SS
  • OSS Members

SEAN’s Paradise

I think that My Life as Software Engineer was torrible , but it’s role for social is important so, I keep going for better life & software development

chapter 1: Setting Up for Your Adventure

1.1 Setting Up Your Windows PC

Install Python

python을 다음 사이트에서 받는다.

https://www.python.org/downloads/windows/

인스톨을 특정 디렉토리에 인스톨한다.

D:\SEANLAB\PYTHON\Python3.7\Lib\site-packages\mcpi\minecraft.py

그리고 윈도우 시스템 설정에서 path를 잡아 준다.

one drive에서 다음 경로로 가면 MinecraftPythonAPI.zip 인스톨 한다.

D:\OneDrive\OneDrive_4619\OneDrive - leverage innovative users\devtools\minecraft

minecraft.py 화일을 열어

@staticmethod
def create(address = "localhost", port = 4711):
return Minecraft(Connection(address, port))

다음과 같이 변경한다.

@staticmethod
def create(address = "192.168.30.9", port = 4711):
return Minecraft(Connection(address, port))

Install JDK

다음 사이트에서 받는다.

http://www.java.com/en/download/

윈도우 시스템 변수에 JAVA_HOME C:Program FilesJavajdk1.8.0_151 그리고 path 변수에

C:\Program Files\Java\jdk1.8.0_151\bin

를 넣는다.

Install Eclipse

다음 사이트에서 받는다.

http://www.eclipse.org

인스톨 후 실행 시킨후 Help-Eclipse Market Place에서 Pydev를 찾아서 인스톨 한다.

1.2 Setting Up Your Mac

skip this sub chapter..

1.3 Setting Up Your Raspberry Pi

skip this sub chapter..

1.4 Getting to Know IDLE

IDLE에 다음 코드를 입력해 보자

from mcpi.minecraft import Minecraft
from mcpi import block
mc = Minecraft.create()
mc.postToChat("test")

mc.postToChat(4+5)


mc.postToChat(178+234)

1.5 Testing Your Minecraft Python Setup

1.6 Python이란

Interpreter,no compile

Python is a high-level programming language, with applications in numerous areas, including web programming, scripting, scientific computing, and artificial intelligence. It is very popular and used by organizations such as Google, NASA, the CIA, and Disney. Python is processed at runtime by the interpreter. There is no need to compile your program before executing it.

Python 3.X,CPython

The three major versions of Python are 1.x, 2.x and 3.x. These are subdivided into minor versions, such as 2.7 and 3.3. Code written for Python 3.x is guaranteed to work in all future versions. Both Python Version 2.x and 3.x are used currently. This course covers Python 3.x, but it isn’t hard to change from one version to another.

Python has several different implementations, written in various languages. The version used in this course, CPython, is the most popular by far.

print(‘Hello world!’)

chapter 2: 변수로 이동하기

2.1 프로그램이란 무엇인가

컴퓨터가 특정한 업무를 할 수 있도록 일련의 명령 집합이다.

2.2 변수값 저장하기

이 장에서 배우게 될 중요한 내용은 변수이다. variable 로 표현되며 여러가지 내용물을 채울 수 있는 모양이 변형되는 그릇이라고 생각하면 된다.

pickaxes = 12 할당해 보자.

bread=145 할당해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
import time

pickaxes = 12

bread=145

time.sleep(2)
mc.postToChat(pickaxes)

time.sleep(2)
mc.postToChat(bread)

다음은 입력이 안된다.

pickaxes = 12 iron = 30 cobblestone = 25

상기처럼 계속 입력행태가 들어가면 오류가 난다.

Syntax Rules for Variables

다음은 변수로 쓸수 없는 규칙이다.

Don’t include symbols in your variable names, except for underscores (_), or you’ll get a syntax error.

Don’t start a variable name with a number, as in 9bread. Using numbers elsewhere in a variable name is fine, as in bread9.

You don’t need to add spaces on either side of the equal sign: your program will run fine without them. But they do make the code easier to read, so it’s a good idea to add them.

변수 이름에 심볼을 넣으면 안된다.예외 _ 숫자로 첫 변수이름을 쓰면 안된다. 예 ,9bread, bread9 OK 할당 (=) 기호에 스페이스를 넣을 필요가 없다.

변수에 값이 저장되었더라도, 그것은 저장이 안된다. 변수값은 컴퓨터의 임시 저장소에 저장된다. 따라서 프로그램이 바뀌거나 하면 값이 사라지게 된다. IDLE에서 변수값이 저장되는지 확인해 보자.

변수값 바꾸기

변수는 변경이 가능하다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
import time

pickaxes = 12

bread=145

time.sleep(2)
mc.postToChat(pickaxes)


time.sleep(2)
mc.postToChat(bread)


time.sleep(2)

pickaxes = 30
bread=20

time.sleep(2)
mc.postToChat(pickaxes)


time.sleep(2)
mc.postToChat(bread)

Integers

정수를 의미한다. 다음에서 x,y,z 변수값을 넣어 보자. 라즈베리 파이에서 평면은 X : -127 ~ 127 Y : -127 ~ 127 Z : -127 ~ 127 공간 안에서만 입력할 수 있다. 프로그램상에서는 다양한 값을 넣을 수 있다.

from mcpi.minecraft import Minecraft
import mcpi.block as block
import time

mc = Minecraft.create()


#Set x, y, and z variables to represent coordinates

x = 60
y = 1
z = 113
"""
x = 0
y = 0
z = 0
"""
#Change the player's position
# mc.player.setTilePos(x, y, z)
mc.player.setTilePos(x, y, z)

time.sleep(5)

mc.postToChat("this is sean notebook")

Floats

정수를 포함한 소수까지 확장은 넓은 변수이다. 소숫점 이하 정확한 지점까지 이동해 보자.

#Connect to Minecraft
from mcpi.minecraft import Minecraft
mc = Minecraft.create()

#Set x, y, and z variables to represent coordinates
x = 63.5
y = 1.0
z = 113.5

#Change the player's position
mc.player.setPos(x, y, z)

2.3 타임 모듈을 이용해서 천천히 또는 잠시 대기상태를 만들어보자

player를 좀 느리게 처리를 하려면 다음 모듈을 쓰면 된다.

import time

time.sleep(초)

2.4 Debugging

Everyone makes mistakes

다음을 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

#Set x, y, and z variables to represent coordinates
#x = 63.5
y = 1.0
z = 113.5

#Change the player's position
mc.player.setPos(x, y, z)

버그를 수정해 보자. 버그 1

from mcpi.minceraft inport Minecraft
# mc = Minecraft.create()

x = 10
y = 11
z = 12

버그를 수정해 보자. 버그 2

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

x = 120
y = 4
z = -12

# mc.player.setPos(x, z, y)
mc.player.setTilePos(x, y, z)

2.5 What You Learned

player position

variables - integers - floats

setPos() setTilePos() time.sleep(초)

chapter 3: Building Quickly and Traveling Far with Math

이 장에서는 블락과 복잡한 구조물을 만드는 법을 배우도록 하겠다.

3.1 Expressions and Statements

You can combine values, variables, and operators to create small pieces of code called expressions, like 2 + 2. Expressions can be combined into statements

3.2 Operators

operators are used to alter and combine numbers.

Addition

다음은 출력해 보자

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

mc.postToChat(3+4)

Mission #5: Stack Blocks

여기서는 setBlock() 함수를 써보자 다음 코드에서 알수 있듯이 x,y,z,blockid가 들어간다. 다음을 실행해 보자. block id =0 인경우는 Air로 블럭을 지우는 효과가 있다.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()

# x = 6
# y = 5
# z = 28
x = 100
y = 1
z = -100
# pos = mc.player.getTilePos()
# x = pos.x
# y = pos.y
# z = pos.z


time.sleep(2)
mc.player.setPos(x,y,z-5)

blockType = 103
#blockType = 0
mc.setBlock(x, y, z, blockType)

time.sleep(2)

y = y + 1
mc.setBlock(x, y, z, blockType)
time.sleep(2)

y = y + 1
mc.setBlock(x, y, z, blockType)

time.sleep(2)
y = y + 1
mc.setBlock(x, y, z, blockType)

block id는 아래 자세히 나와 있다.

_images/chapter3-1.png _images/chapter3-2.png _images/chapter3-3.png ./img/chapter3-4.png ./img/chapter3-5.png ./img/chapter3-6.png ./img/chapter3-7.png ./img/chapter3-8.png ./img/chapter3-9.png

Mission #6: Super Jump

점프를 해보자. 다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
import time

mc = Minecraft.create()

position = mc.player.getTilePos()
x = position.x
y = position.y
z = position.z

y = y + 10
time.sleep(5)
mc.player.setTilePos(x, y, z)

Subtraction

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

mc.postToChat(3-4)

Mission #7: Change the Blocks Under You

발밑에 용암을 만들고 용암에 빠지지 않도록 이동하는 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
import time


mc = Minecraft.create()

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
blockType = 10

y = y - 1

time.sleep(5)

mc.setBlock(x, y, z, blockType)

mc.player.setTilePos(x-3,y,z-3)

Using Math Operators in Arguments

다음 코드를 실행해 보자. 전달자에 바로 연산자를 넣어서 전달할 수 있다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

x = 145
y = 4
z = -39
blockType = 103
mc.setBlock(x, y, z, blockType)
mc.setBlock(x, y+1, z, blockType)
mc.setBlock(x+2, y , z, blockType)

또는 변수를 지정해서 값을 넣은후 전달해도 된다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

x = 6
y = 1
z = 28
blockType = 103
mc.player.setTilePos(x,y,z-5)
up = 1
mc.setBlock(x, y, z, blockType)
mc.setBlock(x, y + up, z, blockType)

Mission #8: Speed Building

간단한 빌딩을 지어 보자.

다음 코드를 실행해 보자

from mcpi.minecraft import Minecraft
import time

mc = Minecraft.create()

mc.player.setTilePos(20,4,20)

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

width = 3
height = 3
length = 3
blockType = 4
"""
width = 142
height = 4
length = -40
"""


blockType = 4
air = 0
mc.player.setTilePos(3,3,3-5)

time.sleep(5)

mc.setBlocks(x, y, z, x + width, y + height, z + length, blockType)
# mc.setBlocks(x + 1, y + 1, z + 1,
             # x + width - 1, y + height - 1, z + length - 1, air)
mc.setBlocks(x + 1, y + 1, z + 1,x + width - 2, y + height - 2, z + length - 2, 0)

Multiplication

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

mc.postToChat(3*4)

Division

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()


mc.postToChat(12/3)
time.sleep(2)
mc.postToChat(12%3)

time.sleep(2)
mc.postToChat(12//5)

Mission #9: Spectacular Spires

탑을 쌓는 코드를 짜보자.

from mcpi.minecraft import Minecraft
import time

mc = Minecraft.create()

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

height = 3
blockType = 1

time.sleep(3)

# Spire sides: should be same as height
sideHeight = height
mc.setBlocks(x + 1, y, z + 1, x + 3, y + sideHeight - 1, z + 3, blockType)

time.sleep(3)
# Spire point: should be two times the height
pointHeight = height * 2
mc.setBlocks(x + 2, y, z + 2, x + 2, y + pointHeight - 1, z + 2, blockType)

time.sleep(3)
# Spire base: should be half the height
baseHeight = height / 2
mc.setBlocks(x, y, z, x + 4, y + baseHeight - 1, z + 4, blockType)

3.3 Exponents

3*3*3*3 을 실행해 보자.

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

mc.postToChat(3*3*3*3)

3.4 Parentheses and Order of Operations

연산자의 우선순위에 관한 문제이다. When you’re using multiple operators, division and multiplication are evaluated first from left to right, and then addition and subtraction are calculated

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()

time.sleep(2)

vars=5*2-1+4/2

mc.postToChat(vars)

time.sleep(2)
mc.postToChat(5*2-1+4/2)


time.sleep(2)
mc.postToChat(6*3-2)


time.sleep(2)
mc.postToChat(6*(3-2))

3.5 Handy Math Tricks

Shorthand Operators

코딩에서 쓰이는 축약 연산 표현이다.

sheep=6 sheep=sheep+5 sheep +=5

다음과 같이 많이 쓰인다.

• Addition (+=)        var= var+x
• Subtraction (-=)     var= var-x
• Multiplication (*=)  var= var*x
• Division (/=)        var= var/x

Playing with Random Numbers

파이썬은 임의의 숫자를 생성하는 함수를 제공한다.

import random diceValue = random.randint(1, 6)

Mission #10: Super Jump Somewhere New!

다음 코드를 실행해 보자

from mcpi.minecraft import Minecraft
import time

mc = Minecraft.create()
mc.player.setTilePos(100,4,20)
import random

pos = mc.player.getPos()
x = pos.x
y = pos.y
z = pos.z
time.sleep(5)

x += random.randrange(-10, 11)
y += random.randrange(0, 11)
z += random.randrange(-10, 11)
mc.player.setPos(x, y, z)

3.5 What You Learned

addition, subtraction, multiplication, and division

random numbers

chapter 4: Chatting with Strings

4.1 What Are Strings?

A string data type includes any amount of text, from a single letter or symbol—like “a” or “&”—to a large block of text

Mission #11: Hello, Minecraft World

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()
time.sleep(2)
mc.postToChat("Hello, Minecraft World")
time.sleep(2)
mc.postToChat("This is sean kim")

player가 어느 위치에 있는지 출력을 해보자.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()

pos = mc.player.getTilePos()

x=pos.x
y=pos.y
z=pos.z

mc.postToChat(x)
mc.postToChat(y)
mc.postToChat(z)

time.sleep(2)
mc.postToChat("Hello, Minecraft World")
time.sleep(2)
mc.postToChat("This is sean kim")

4.2 The print() Function

postToChat 역할과 동일한 역할을 하는 함수이다. 파이썬 코드에서 string 출력을 위해서 많이 쓰인다.

4.3 The input() Function

사용자의 입력값을 기다릴때 쓰인다.

다음 코드를 입력해 보자.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()
mcid=mc.getPlayerEntityIds()
mc.postToChat(mcid)

blockType = int(input("Enter a block type: "))
pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
time.sleep(2)
mc.setBlock(x, y, z, blockType)

time.sleep(2)
mc.player.setTilePos(x,y,z-5)
mc.player.setTilePos(mcid)
mc.postToChat("mission cleared")

Mission #12: Write Your Own Chat Message

다음 코드를 입력해 보자

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

message = input("Enter your message: ")
mc.postToChat(message)

4.4 Joining Strings

String을 합치는 작업을 말한다.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()

firstName='John'
LastName='Lenon'

fullname=firstName+LastName

time.sleep(2)
mc.postToChat(fullname)

Converting Numbers to Strings

숫자를 String으로 표현해서 나타낼때가 있는데 다음의 경우 숫자를 String으로 변경해서 표현한다. the str() function, which converts non-string data types into strings

다음 코드를 실행해 보자.

import time
from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos1 = mc.player.getTilePos()
x1 = pos1.x
y1 = pos1.y
z1 = pos1.z

time.sleep(10)

pos2 = mc.player.getTilePos()
x2 = pos2.x
y2 = pos2.y
z2 = pos2.z

# Compare the difference between the starting position and ending position
xDistance = x2 - x1
yDistance = y2 - y1
zDistance = z2 - z1

#Post the results to the chat
mc.postToChat("The player has moved x: " + str(xDistance) + ", y: "
    + str(yDistance) + ", and z: " + str(zDistance))

Mission #13: Add Usernames to Chat

다음 코드를 출력해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

userName = input("Enter your username: ")
message = input("Enter your message: ")
mc.postToChat(userName + ": " + message)

4.5 Converting Strings to Integers with int()

the int() function converts non-integer data types into integer

Mission #14: Create a Block with Input

블락타입을 입력받아서 처리하는 코드를 출력해 보자.

from mcpi.minecraft import Minecraft
import time
mc = Minecraft.create()
mcid=mc.getPlayerEntityIds()
mc.postToChat(mcid)

blockType = int(input("Enter a block type: "))
pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
time.sleep(2)
mc.setBlock(x, y, z, blockType)

time.sleep(2)
mc.player.setTilePos(x,y,z-5)
mc.player.setTilePos(mcid)
mc.postToChat("mission cleared")

4.6 Bounce Back from Errors

Python uses exception handling to make sure your program can recover from errors and continue running when they occur

기본 형은 try:

XXX
except:
XXXX

Mission #15: Only Numbers Allowed

다음 숫자만 입력할 수 있는 코드를 출력해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

try:
    blockType = int(input("Enter a block type: "))
    mc.setBlock(x, y, z, blockType)
except:
    mc.postToChat("You did not enter a number! Enter a number next time.")

Mission #16: Sprint Record

두 지점 이동한 거리를 출력하는 코드를 짜보자. 중간에 sleep을 두자

import time
from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos1 = mc.player.getTilePos()
x1 = pos1.x
y1 = pos1.y
z1 = pos1.z

time.sleep(10)

pos2 = mc.player.getTilePos()
x2 = pos2.x
y2 = pos2.y
z2 = pos2.z

# Compare the difference between the starting position and ending position
xDistance = x2 - x1
yDistance = y2 - y1
zDistance = z2 - z1

#Post the results to the chat
mc.postToChat("The player has moved x: " + str(xDistance) + ", y: "
    + str(yDistance) + ", and z: " + str(zDistance))

4.7 What You Learned

string print join string user input data type change handled exception

chapter 5: Figuring Out What’s True and False with Booleans

5.1 Boolean Basics

A Boolean is a bit like a light switch: it is either True (on) or False (off)

Mission #17: Stop Smashing Blocks!

마인크래프트에서 immutable 설정을 on으로 하는 프로그램을 실행해 봅시다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

mc.setting("world_immutable", True)

반대로 immutable 설정을 off로 하는 프로그램을 실행해 봅시다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

mc.setting("world_immutable", False)

5.2 Concatenating Booleans

이전장에서 배운것처럼 boolean 변수도 string으로 변환될 필요가 있다.

agree = True print(“I agree: ” + str(agree)) I agree: True

5.3 Comparators

연산자를 의미한다. 많이 쓰이는 기본적인 연산자들은 다음과 같다.

• Equal to (==)
• Not equal to (!=)
• Less than (<)
• Less than or equal to (<=)
• Greater than (>)
• Greater than or equal to (>=)

Equal To

두개의 값이 동일한지 판단을 할때 쓰인다.

Mission #18: Am I Swimming?

다음 코드를 실행해 보자. block type이 물인지 판별하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getPos()
x = pos.x
y = pos.y
z = pos.z

blockType = mc.getBlock(x, y, z)
mc.postToChat(blockType == 9)

block type이 9이면 물이다.

Mission #19: Am I Standing in Something Other Than Air?

공중에 떠있는지 확인 하는 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getPos()
x = pos.x
y = pos.y
z = pos.z

blockType = mc.getBlock(x, y, z)
notAir = blockType != 0
mc.postToChat("The player is not standing in air: " + str(notAir))

Mission #20: Am I Above the Ground?

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
highestBlockY = mc.getHeight(x, z)
aboveGround = y >= highestBlockY
mc.postToChat("The player is above ground: " + str(aboveGround))

Mission #21: Am I Close to Home?

다음은 임의의 홈을 설정후 가깝게 있는지 확인하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import math

homeX = 10
homeZ = 10
pos = mc.player.getTilePos()
x = pos.x
z = pos.z
distance = math.sqrt((homeX - x) ** 2 + (homeZ - z) ** 2)
far = distance <= 40
mc.postToChat("Your house is nearby: " + str(far))

5.4 Logical Operators

and,or,not 연산자등이 있다.

다음은 and 연산자에 대한 두개값의 결과이다.

./img/chapter5-1.png

Mission #22: Am I Entirely Underwater?

player가 물밑에 있는지 확인하는 로직이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getPos()
x = pos.x
y = pos.y
z = pos.z

blockType = mc.getBlock(x, y, z)
blockType2 = mc.getBlock(x, y + 1, z)

underwater = blockType == 9 and blockType2 == 9
mc.postToChat("The player is underwater: " + str(underwater))

다음은 or 연산자에 대한 두개값의 결과이다.

./img/chapter5-2.png

Mission #23: Am I in a Tree?

다음은 player가 나무에 있는지 확인하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getPos()
x = pos.x
y = pos.y
z = pos.z

blockType = mc.getBlock(x, y - 1, z)
inTree = blockType == 18 or blockType == 11
mc.postToChat("The player is in a tree: " + str(inTree))

Mission #24: Is This Block Not a Melon?

다음 코드는 멜론 블럭인지 확인하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

x = 10
y = 11
z = 12
melon = 103
block = mc.getBlock(x, y, z)

noMelon = not block == melon

mc.postToChat("You need to get some food: " + str(noMelon))

Logical Operator Order

로직컬 연산자는 다음순으로 우선순위가 있다.

1. not
2. and
3. or

Mission #25: Am I in the House?

player가 집에 있는지 확인하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

buildX = 10
buildY = 11
buildZ = 12
width = 10
height = 5
length = 6

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

inside = buildX < x < buildX + width and buildY < y < buildY + height and buildZ < z < buildZ + length
mc.postToChat("The player is at home: " + str(inside))

5.5 What You Learned

이 장에서는 Booleans, comparators, and logical operators 등을 배웠다.

chapter 6: Making Mini-Games with if Statements

이 장에서는 조건문에 대해서 배워 보도록 하자.

6.1 Using if Statements

Mission #26: Blast a Crater

다음은 사용자 입력을 받아서 입력 하라고 하면 블력을 생성하는 프로그램이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
answer = input("Create a crater? Y/N ")

if answer == "Y":
    pos = mc.player.getPos()
    mc.setBlocks(pos.x + 1, pos.y + 1, pos.z + 1, pos.x - 1, pos.y - 1, pos.z - 1, 0)
    mc.postToChat("Boom!")

Mission #27: Prevent Smashing, or Not

다음은 immutable을 활용해서 else 구문을 적용한 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

answer = input("Do you want to make the blocks immutable? Y/N ")

if answer == "Y":
    mc.setting("world_immutable", True)
    mc.postToChat("World is immutable")
else:
    mc.setting("world_immutable", False)
    mc.postToChat("World is mutable")

Mission #28: Offer a Gift

다이아몬드인지를 판별하고 다른 조건이 나오고…마지막 조건은 특정 위치로 다이아몬드를 가져 가라는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
x = 10
y = 11
z = 12
gift = mc.getBlock(x, y, z)

# if gift is a diamond block
if gift == 57:
    mc.postToChat("Thanks for the diamond.")
# else if gift is a sapling
elif gift == 6:
    mc.postToChat("I guess tree saplings are as good as diamonds...")
else:
    mc.postToChat("Bring a gift to " + str(x) + ", " + str(y) + ", " + str(z))

Mission #29: Teleport to the Right Place

if,elif,else문에 대한 활용 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


points = int(input("Enter your points: "))
if points > 6:
    mc.player.setPos(32, 18, -38)
elif points > 4:
    mc.player.setPos(60, 20, 32)
elif points > 2:
    mc.player.setPos(112, 10, 112)
elif points <= 2:
    mc.player.setPos(0, 12, 20)
else:
    mc.postToChat("I don't know what to do with that information.")

Nested if Statements

이중 if문을 가질때 안쪽에 들어가는 if문을 말한다.

Mission #30: Open a Secret Passage

이번 미션을 수행하기 위하여 이전장에서 실행했던 빌딩을 지어보도록 하자.

from mcpi.minecraft import Minecraft
import time

mc = Minecraft.create()

mc.player.setTilePos(20,1,20)

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
"""
width = 3
height = 1
length = 3
"""

width = 10
height = 5
length = 6



blockType = 4

#blockType = 0

air = 0


time.sleep(5)
mc.player.setTilePos(x-1,y,z-1)

mc.setBlocks(x, y, z, x + width, y + height, z + length, blockType)
#mc.setBlocks(x , y , z ,x + width , y + height , z + length , air)
mc.setBlocks(x + 1, y + 1, z + 1,x + width - 2, y + height - 2, z + length - 2, 0)
diamond=57
mc.setBlocks(x+5, y, z, x + 6, y + 1, z + 1, diamond)

그리고 다음 코드를 실행해 보자. 다이아몬드 블럭을 체크한후 다이아몬드 블럭이면 블럭을 지우는 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

# x = 10
# y = 11
# z = 12

x = 20
y = 1
z = 20


gift = mc.getBlock(x+5, y, z+1)
mc.postToChat(gift)

if gift != 0:
    if gift == 57:
#         mc.setBlocks(5, -2, 5, 6, -1, 6, 0)
        mc.setBlocks(x+5, y, z, x+6, y+1, x+1, 0)
    else:
#         mc.setBlocks(4, -3, 4, 7, -3, 4, 10)
        mc.setBlocks(20, 1, 20, 19, 1, 19, 0)
else:
    mc.postToChat("Place an offering on the pedestal.")

6.2 Using if Statements to Test a Range of Values

입력된 숫자나 기타 조건이 범위가 주어질때 쓰인다.

다음 코드를 입력해 보자. x,y,z 좌표값이 잘못 입력했을때 체크하는 구문이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

valid = True

x = int(input("Enter x: "))
y = int(input("Enter y: "))
z = int(input("Enter z: "))

if not -127 < x < 127:
    valid = False
# check if y is not between -63 and 63
if not -63 < y < 63:
    valid = False
# check if z is not between -127 and 127
if not -127 < z < 127:
    valid = False

if valid:
    mc.player.setPos(x, y, z)
else:
    mc.postToChat("Please enter a valid location")

6.3 Boolean Operators and if Statements

Mission #32: Take a Shower

skip this mission

6.4 What You Learned

if statements, else statements, and elif statements

chapter 7: Dance Parties and Flower Parades with while Loops

7.1 A Simple while Loop

while 구문은 아래 구조로 되어 있다.

count = 1
while count <= 5:
    print(count)
    count += 1
print("Loop finished")

Mission #33: A Random Teleportation Tour

random 함수를 이용하여 임의로 움직이는 코드를 짜보자.

import time
import random
from mcpi.minecraft import Minecraft
mc = Minecraft.create()

count = 0
while count < 5:
    x = random.randrange(-127, 128)
    y = random.randrange(0, 64)
    z = random.randrange(-127, 128)

    mc.postToChat("x:"+str(x))
    mc.postToChat("Y:"+str(y))
    mc.postToChat("Z:"+str(z))
    mc.player.setTilePos(x, y, z)
    count += 1
    time.sleep(10)

7.2 Controlling Loops with a Count Variable

Mission #34: The Watery Curse

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

count = 0

while count < 30:
    pos = mc.player.getPos()
    mc.setBlock(pos.x, pos.y, pos.z, 8)
    count += 1
    time.sleep(1)

Infinite while Loops

무한 반복을 의미 한다.

while True:
    print("Hello")


while True:
    print("Hello")
print("This line is never reached")

Mission #35: Flower Trail

skip this mission

7.3 Fancy Conditions

다음 코드를 보자 초기값은 while 루프가 실행되지만 사용자 입력값에 따라서 빠져나갈 수 있다.

continueAnswer = "Y"
coins = 0
while continueAnswer == "Y":
    coins = coins + 1
    continueAnswer = input("Continue? Y/N")
print("You have " + str(coins) + " coins")

Mission #36: Diving Contest

skip this mission

Boolean Operators and while Loops

boolean operator들도 while 문에 쓰인다.

password = "cats"
passwordInput = input("Please enter the password: ")
attempts = 0
while password != passwordInput and attempts < 3:
    attempts += 1
    passwordInput = input("Incorrect. Please enter the password: ")
if password == passwordInput:
    print("Password accepted.")

Checking a Range of Values in while Loops

while에 변수값 범위를 지정할 수 있다.

position = 0
while 0 <= position <= 10:
    position = int(input("Enter your position 0-10: "))
print(position)

Mission #37: Make a Dance Floor

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
import time

pos = mc.player.getTilePos()
floorX = pos.x - 2
floorY = pos.y - 1
floorZ = pos.z - 2
width = 5
length = 5
block = 41
mc.setBlocks(floorX, floorY, floorZ,
             floorX + width, floorY, floorZ + length, block)

while floorX <= pos.x <= floorX + width and floorZ <= pos.z <= floorZ + length:
    if block == 41:
        block = 57
    else:
        block = 41
    mc.setBlocks(floorX, floorY, floorZ,
                 floorX + width, floorY, floorZ + length, block)
    # get the player's position
    pos = mc.player.getTilePos()
    # wait 0.5 seconds
    time.sleep(0.5)

Nested if Statements and while Loops

whlile문 안에 if문이 들어가는 경우이다.

word = "mine"
count = 0
while count < 50:
    print(word)
    if word == "mine":
        word = "craft"
    else:
        word = "mine"

Mission #38: The Midas Touch

다음 미션을 수행해 보자. player가 지나간 자리는 모두 황금색으로 변하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

air = 0
water = 9

while True:
    pos = mc.player.getTilePos()
    blockBelow = mc.getBlock(pos.x, pos.y - 1, pos.z)

    if blockBelow != air and blockBelow != water:
        # change the block below the player to gold
        mc.setBlock(pos.x, pos.y - 1, pos.z, 41)

7.4 Ending a while Loop with break

while문을 빠져 나갈때는 break를 쓴다.

while True:
    userInput = input("Enter a command: ")
    if userInput == "exit":
        break
    print(userInput)
 print("Loop exited")

Mission #39: Create a Persistent Chat with a Loop

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

userName = input("Enter your username: ")

while True:
    message = input("Enter your message: ")
    if message == "exit":
        break
    mc.postToChat(userName + ": " + message)

Mission #40: Hot and Cold

from mcpi.minecraft import Minecraft
import math
import time
import random
mc = Minecraft.create()

destX = random.randint(-127, 127)
destZ = random.randint(-127, 127)
destY = mc.getHeight(destX, destZ)

print(destX, destY, destZ)

block = 57
mc.setBlock(destX, destY, destZ, block)
mc.postToChat("Block set")

while True:
    pos = mc.player.getPos()
    distance = math.sqrt((pos.x - destX) ** 2 + (pos.z - destZ) ** 2)

    if distance == 0:
        break

    if distance > 100:
        mc.postToChat("Freezing")
    elif distance > 50:
        mc.postToChat("Cold")
    elif distance > 25:
        mc.postToChat("Warm")
    elif distance > 12:
        mc.postToChat("Boiling")
    elif distance > 6:
        mc.postToChat("On fire!")
    elif distance == 0:
        mc.postToChat("Found it")

7.4 What You Learned

while loops loops with conditions

chapter 8: Functions Give You Superpowers

Function이란 다음 특징을 가진다.

Reusability

Functions save time. Because you don’t have to rewrite the same code over and over again, writing a program is faster and easier.

Debugging

By containing tasks in groups of code, it is easier to identify where a problem originates and make changes to fix the problem.

Modularity

You can develop different functions to use in the same program independently of one another. This makes it easier to share code with other people and reuse functions in other programs. Scalability Using functions makes it easier to increase the size of a program and the amount of data it processes.

8.1 Defining Your Own Functions

함수 정의는 다음처럼 한다.

def greeting():
print("Hello")
print("Nice to meet you")

함수 호출은 정의한대로 호출하면 된다.

greeting()

Functions Take Arguments

함수에 전달자가 들어가는 경우가 대부분이다. 아래 예제를 보자.

def fancyGreeting(personName):
    print("Hello, " + personName)


fancyGreeting("Mario")
fancyGreeting("Steve")

fancyGreeting() 호출하게 되면 전달자가 없으므로 오류가 난다.

Mission #41: Build a Forest

숲을 만드는 코드를 짜보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


def growTree(x, y, z):
    """Creates a tree at the coordinates given"""
    wood = 17
    leaves = 18

    # trunk
    mc.setBlocks(x, y, z, x, y + 5, z, wood)

    # leaves
    mc.setBlocks(x - 2, y + 6, z - 2, x + 2, y + 6, z + 2, leaves)
    mc.setBlocks(x - 1, y + 7, z - 1, x + 1, y + 7, z + 1, leaves)

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z


growTree(x + 1, y, z)
growTree(x + 10, y, z)
growTree(x + 20, y, z)

Refactoring a Program

코드를 재수정 또는 구조를 변경하는 작업들을 refactoring 이라고 한다.

다음 코드를 변경하는 작업을 해보자.

name1 = input("Hello, what is your name?")
print("Pleased to meet you, " + name1)
name2 = input("Hello, what is your name?")
print("Pleased to meet you, " + name2)
name3 = input("Hello, what is your name?")
print("Pleased to meet you, " + name3)

def helloFriend():
    name = input("Hello, what is your name?")
    print("Pleased to meet you, " + name)

helloFriend()
helloFriend()
helloFriend()

Mission #42: Refactor Away

다음 코드를 refactoring 작업을 해보도록 하자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time


def makeMelon(x, y, z):
    pos = mc.player.getPos()
    x = pos.x
    y = pos.y
    z = pos.z
    mc.setBlock(x, y, z, 103)
    time.sleep(10)

pos = mc.player.getPos()
x = pos.x
y = pos.y
z = pos.z

makeMelon(x, y + 1, z)
makeMelon(x, y + 3, z)
makeMelon(x + 2, y, z)
makeMelon(x, y, z)
makeMelon(x, y + 1, z + 2)
makeMelon(x, y, z + 3)

Commenting with Docstrings

코멘트 처리를 해서 코드에 대한 설명을 붙여서 이해를 돕는 역할을 많이 한다.

def duplicateString(stringToDbl):
    """ Prints a string twice on the same line.
    stringToDbl argument should be a string """
    print(stringToDbl * 2)

실제 코멘트들은 실행코드에는 안들어 가지만 메모리에는 포함이 되므로 과도한 코멘트는 지향이 필요하다.

Line Breaks in Arguments

라인 문장이 길때 다음줄을 이용하는것이 가독성을 위해서 좋다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
pos = mc.player.getPos()
width = 10
height = 12
length = 13
block = 103
mc.setBlocks(pos.x, pos.y, pos.z,
             pos.x + width, pos.y + height, pos.z + length, block)

Function Return Values

함수를 이용하는 목적중에 하나가 결과값을 도출하는 데 있다. 아래 코드를 살펴보자.

def calculateCookiePrice(cost):
    price = cost + 2
    price = price * 10
    return price

Mission #43: Block ID Reminder

다음 코드를 실행해 보자. 함수를 호출하면 block id를 리턴하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


def melon():
    return 103


def water():
    return 9


def wool():
    return 35


def lava():
    return 10


def tnt():
    return 46


def flower():
    return 37


def diamondBlock():
    return 57


block = melon()
pos = mc.player.getTilePos()
mc.setBlock(pos.x, pos.y, pos.z, block)

8.2 Using if Statements and while Loops in Functions

fucntion에서 if문과 while loop를 쓰는법을 배워 보도록 하자.

if Statements

다음처럼 문자로 입력한 부분을 숫자로 처리하는 구문을 보자

def wordToNumber(numToConvert):
""" Converts a number written as a word to an integer """
    if numToConvert == "one":
        numAsInt = 1
    elif numToConvert == "two":
        numAsInt = 2
    elif numToConvert == "three":
        numAsInt = 3
    elif numToConvert == "four":
        numAsInt = 4
    elif numToConver == "five":
        numAsInt = 5
    return numAsInt

Mission #44: Wool Color Helper

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


def getWoolState(color):
    """Takes a color as a string and returns the wool block state
    for that color"""

    if color == "pink":
        blockState = 6
    elif color == "black":
        blockState = 15
    elif color == "grey":
        blockState = 7
    elif color == "red":
        blockState = 14
    elif color == "green":
        blockState = 5
    elif color == "brown":
        blockState = 0
    elif color == "yellow":
        blockState = 4
    elif color == "blue":
        blockState = 11
    elif color == "light blue":
        blockState = 3
    elif color == "purple":
        blockState = 10
    elif color == "cyan":
        blockState = 9
    elif color == "orange":
        blockState = 1
    elif color == "light grey":
        blockState = 8

    return blockState

colorString = input("Enter a block color: ")
state = getWoolState(colorString)

pos = mc.player.getTilePos()
mc.setBlock(pos.x, pos.y, pos.z, 35, state)

while Loops

def printMultiple(toPrint, repeats):
""" Prints a string a number of times determined by the repeats variable """
count = 0
while count < repeats:
print(toPrint)
count += 1

def doubleUntilHundred(numberToDbl):
""" Doubles a number until it is greater than 100. Returns the number of
    times the number was doubled """
    count = 0
    while numToDbl < 100:
        numberToDbl = numberToDbl * 2
        count += 1
    return count

Mission #45: Blocks, Everywhere

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import random


def randomBlockLocations(blockType, repeats):
    """Creates blocks at random locations"""
    count = 0
    while count < repeats:
        x = random.randrange(-127, 128)
        z = random.randrange(-127, 128)
        y = mc.getHeight(x, z)
        mc.setBlock(x, y, z, blockType)
        count += 1

randomBlockLocations(103, 10)
randomBlockLocations(35, 37)
randomBlockLocations(57, 102)

8.3 Global and Local Variables

글로벌 변수와 로컬 변수에 대해서 알아 보자.

eggs = 12
def increaseEggs():
     eggs += 1
    print(eggs)
increaseEggs()

상기 코드는 에러를 표현한다. 두개의 eggs값이 다르기때문이다.

>>> eggs =12
>>> def increaseEggs():
    eggs=0
    eggs +=1
    print(eggs)


>>> increaseEggs()
1
>>> print(eggs)
12
>>>

로컬 변수와 차별을 위해 글로벌 변수 앞에는 global 이라고 표현한다. 상기에는 묵시적 global로 표기된 eggs값을 로컬 변수 eggs값에서 변경할 수 없다.

eggs = 12
def increaseEggs():
    global eggs
    eggs += 1
    print(eggs)


increaseEggs()

Mission #46: A Moving Block

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time


def calculateMove():
    """ Changes the x and z variables for a block. If the block
    in front of the block is less than 2 blocks higher it will move
    forward, otherwise it will try to move left, then backwards,
    then finally right."""
    global x
    global y
    global z

    currentHeight = mc.getHeight(x, z) - 1

    forwardHeight = mc.getHeight(x + 1, z)
    rightHeight = mc.getHeight(x, z + 1)
    backwardHeight = mc.getHeight(x - 1, z)
    leftHeight = mc.getHeight(x, z - 1)

    if forwardHeight - currentHeight < 3:
        x += 1
    elif rightHeight - currentHeight < 3:
        z += 1
    elif leftHeight - currentHeight < 3:
        z -= 1
    elif backwardHeight - currentHeight < 3:
        x -= 1

    y = mc.getHeight(x, z)


pos = mc.player.getTilePos()
x = pos.x
z = pos.z
y = mc.getHeight(x, z)

while True:
    # calculate block movement
    calculateMove()

    # place block
    mc.setBlock(x, y, z, 103)

    # wait
    time.sleep(1)

    # remove the block
    mc.setBlock(x, y, z, 0)

8.4 What You Learned

create and call functions

return statements

functions return values

loops and if statements inside functions

chapter 9: Hitting Things with Lists and Dictionaries

이 장에서는 데이터 타입으로 List 와 Dictionary를 배워보도록 하겠다.

9.1 Using Lists

리스트는 다음처럼 표기한다.

emptyList = []

빈 리스트를 작성할 수도 있고 다음처럼 초기화 값을 갖는 리스트도 표현 가능하다.

noodleSoup = ["water", "soy sauce", "spring onions", "noodles", "beef"]

초기화 값은 integer 또는 string을 집어 넣을 수 있다.

wackyList = ["cardigan", 33, "goofballs"]

Accessing a List Item

리스트의 호출은 다음과 같이 한다.

print(noodleSoup[0])

Changing a List Item

list값은 mutable이다. 따라서 변경가능하다는 얘기다.

다음처럼 직접 접근해서 변경가능하다.

noodleSoup[4] = "chicken"

Mission #47: High and Low

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

heights = [100, 0]
count = 0

while count < 60:
    pos = mc.player.getTilePos()

    if pos.y < heights[0]:
        heights[0] = pos.y
    elif pos.y > heights[1]:
        heights[1] = pos.y

    count += 1
    time.sleep(1)

mc.postToChat("Lowest: " + str(heights[0]))
mc.postToChat("Highest: " + str(heights[1]))

이동한 곳의 가장 높은곳과 낮은곳을 찾는 코드이다. 약간의 시간이 필요하다.

9.2 Manipulating Lists

리스트는 내장 함수로 추가 삭제가 가능하다.

Adding an Item

noodleSoup.append("vegetables")

food = []
food.append("cake")

Inserting an Item

중간에 집어 넣을 수도 있다.

   noodleSoup = ["water", "soy sauce", "spring onions", "noodles", "beef", "vegetables"]

   noodleSoup.insert(3, "pepper")

   ["water", "soy sauce", "spring onions", "pepper", "noodles", "beef", "vegetables"]

만약 리스트를 넘는 곳에 넣게 되면 자동적으로 맨 마지막에 넣어지게 된다.
   noodleSoup.insert(10, "salt")

   ["water", "soy sauce", "spring onions", "pepper", "noodles", "beef","vegetables", "salt"]

Deleting an Item

다음처럼 아이템을 삭제할 수 있다.

del noodleSoup[5]

인덱스 번호를 모를 경우는 다음처럼 처리하면 된다.

beefPosition = noodleSoup.index("beef")
del noodleSoup[beefPosition]

Mission #48: Progress Bar

다음 미션을 수행해 보자. 10개의 유리 상자를 쌓은 다음에 하나씩 barblock으로 교체하는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

pos = mc.player.getTilePos()
x = pos.x + 1
y = pos.y
z = pos.z

# Add 10 glass blocks (block id 20) to this list
blocks = [20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
barBlock = 22  # Lapis lazuli

count = 0
while count <= len(blocks):
    # Add setBlock() for the remaining blocks in the list
    mc.setBlock(x, y, z, blocks[0])
    mc.setBlock(x, y + 1, z, blocks[1])
    mc.setBlock(x, y + 2, z, blocks[2])
    mc.setBlock(x, y + 3, z, blocks[3])
    mc.setBlock(x, y + 4, z, blocks[4])
    mc.setBlock(x, y + 5, z, blocks[5])
    mc.setBlock(x, y + 6, z, blocks[6])
    mc.setBlock(x, y + 7, z, blocks[7])
    mc.setBlock(x, y + 8, z, blocks[8])
    mc.setBlock(x, y + 9, z, blocks[9])

    count += 1

    # Delete the last block in the list
    del blocks[9]

    # Insert a bar block at the first position in the list
    blocks.insert(0, barBlock)

    time.sleep(2)

9.3 Treating Strings like Lists

스크링을 리스트처럼 쓰이기도 한다.

flavor = "Grape"
print(flavor[1])

firstName = "Lyra"
lastName = "Jones"
initials = firstName[0] + " " + lastName[0]
print(initials)
L J

9.4 Tuples

Tuples are a type of list that is immutable 변경이 불가능한 리스트 타입이라고 보면 된다. 표현은 아래처럼 한다.

distance = (5.17, 5.20, 4.56, 53.64, 9.58, 6.41, 2.20)

한개의 값은 다음처럼 입력한다. “,”는 꼭 입력한다.

distance = (5.17,)

Setting Variables with Tuples

tuple은 다음처럼 유용하게 쓰인다.

measurements = 6, 30


width, height = 6, 30

Mission #49: Sliding

tuple을 이용해서 다음처럼 쓸 수 있다.

x = 10
y = 11
z = 12

x, y, z = 10, 11, 12

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import random
import time

pos = mc.player.getPos()
x, y, z = pos.x, pos.y, pos.z

while True:
    x += random.uniform(-0.2, 0.2)
    z += random.uniform(-0.2, 0.2)
    y = mc.getHeight(x, z)

    mc.player.setPos(x, y, z)
    time.sleep(0.1)

Returning a Tuple

tuple로 리턴값을 줄 수 있다.

def getDateTuple(dateString):
year = int(dateString[0:4])
month = int(dateString[5:7])
day = int(dateString[8:10])
return year, month, day

다음처럼 string을 tuple로 리턴할 수 있다.

getDateTuple("1997-09-27")
(1997, 9, 27)

year, month, day = getDateTuple("1997-09-27")

9.4 Other Useful Features of Lists

List Length

리스트의 크기를 다음처럼 구할 수 있다.

>>> noodleSoup = ["water", "soy sauce", "spring onions", "noodles", "beef",
"vegetables"]
>>> print(len(noodleSoup))

Mission #50: Block Hits

60초 동안 블럭을 터치하고 터치한 블럭 갯수를 구하는 코드를 구해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

#Wait 60 seconds
time.sleep(60)

#Get the list of block hits
blockHits = mc.events.pollBlockHits()

#Display the length of the block hits list to chat
blockHitsLength = len(blockHits)
mc.postToChat("Your score is " + str(blockHitsLength))

Randomly Choosing an Item

다음처럼 list에서 임으로 선택하는 것을 쓸 수 있다.

import random
colors = ["red", "green", "blue", "yellow", "orange", "purple"]
print(random.choice(colors))

Mission #51: Random Block

다음처럼 리스트에서 임의로 선택하는 블럭을 쓸 수 있다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import random

pos = mc.player.getTilePos()
x, y, z = pos.x, pos.y, pos.z

blocks = [57, 41, 22, 42, 103]
block = random.choice(blocks)

mc.setBlock(x, y, z, block)

Copying a List

다음 코드를 실행해 보자.

>>> cake = ["Eggs",
"Butter",
"Sugar",
184 Chapter 9
"Milk",
"Flour"]
>>> print(id(cake))

다음처럼 복사할 경우 달라야 되는데 출력해 보면 동일하다. 이건 컴퓨터가 실제로 동일 주소를 가지고 있고 복사한것이 아니다.

>>> cake = ["Eggs",
"Butter",
"Sugar",
"Milk",
"Flour"]
>>> # Store the list in a second variable
>>> chocolateCake = cake
>>> chocolateCake.append("Chocolate")

다음처럼 하면 복사한 다른 개체가 생성된다.

>>> chocolateCake = cake[:]

Items and if Statements

To find out whether a value is in a list, you can use the in operator

다음을 보자.

>>> cake = ["Eggs", "Butter", "Sugar", "Milk", "Flour"]
>>> print("Eggs" in cake)

>>> cake = ["Eggs", "Butter", "Sugar", "Milk", "Flour"]
>>> if "Ham" in cake:
>>> print("That cake sounds disgusting.")
>>> else:
>>> print("Good. Ham in a cake is a terrible mistake.")

>>> cake = ["Eggs", "Butter", "Sugar", "Milk", "Flour"]
>>> if "Ham" not in cake:
>>> print("Good. Ham in a cake is a terrible mistake.")
>>> else:
>>> print("That cake sounds disgusting")

Mission #52: Night Vision Sword

다음 미션을 수행해 보자. 다이아몬드 블럭을 터치했을 경우 빠져 나가는 코드이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

blocks = []
i=0
while i<100:
    hits = mc.events.pollBlockHits()
    i +=1
    if len(hits) > 0:
        hit = hits[0]
        hitX, hitY, hitZ = hit.pos.x, hit.pos.y, hit.pos.z
        block = mc.getBlock(hitX, hitY, hitZ)
        blocks.append(block)

    if 56 in blocks:
        mc.postToChat("You found some diamond ore!")
        break

    time.sleep(0.2)

9.4 Dictionaries

a set of keys 로 주어지는 리스트라고 생각하면 된다.

person = {'name': 'David',
'age': 42,
'favoriteAnimal': 'Snake',
'favoritePlace': 'Inside a cardboard box'}


trainTimes = {1.00: 'Castle Town',
2.30: 'Sheep Farm',
3.15: 'Lake City',
3.45: 'Castle Town',
3.55: 'Storage Land'
}

Accessing Items in Dictionaries

person = {'name': 'David',
'age': 42,
'favoriteAnimal': 'Snake',
'favoritePlace': 'Inside a cardboard box'}
agentName = person['name']

Mission #53: Sightseeing Guide

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

places = {"House": (10, 11, 12),
          "Tower": (20, -2, 3),
          "Store room": (6, 2, 1)}

choice = ""
while choice != "exit":
    choice = input("Enter a location ('exit' to close): ")
    if choice in places:
        location = places[choice]
        x, y, z = location[0], location[1], location[2]
        mc.player.setTilePos(x, y, z)

Changing or Adding an Item ina Dictionary

Dictionary도 변경 추가 가능하다.

person['age'] = 43

삭제도 가능하다.

del person['favoriteAnimal']

Mission #54: Block Hits Score

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

name = ""
scoreboard = {}

while True:
    # Get the player's name
    name = input("What is your name? ")

    # Break loop if name is exit
    if name == "exit":
        break
    mc.postToChat("Go!")

    # Wait 60 seconds
    time.sleep(60)

    # Get the list of block hits
    blockHits = mc.events.pollBlockHits()

    # Display the length of the block hits list to chat
    blockHitsLength = len(blockHits)
    mc.postToChat("Your score is " + str(blockHitsLength))

    scoreboard[name] = blockHitsLength

    print(scoreboard)

9.4 What You Learned

lists, tuples, and dictionaries

wackyList = [“cardigan”, 33, “goofballs”]

distance = (5.17, 5.20, 4.56, 53.64, 9.58, 6.41, 2.20)

person = {‘name’: ‘David’,
‘age’: 42, ‘favoriteAnimal’: ‘Snake’, ‘favoritePlace’: ‘Inside a cardboard box’}

chapter 10: Minecraft Magic with for Loops

10.1 A Simple for Loop

리스트에서 아이템을 꺼내 오는 예제를 보자

noodleSoup = ["water", "soy sauce", "spring onions", "pepper", "noodles",
"beef", "vegetables"]


for ingredient in noodleSoup:
print(ingredient)

Mission #55: Magic Wand

9장에서 pollBlockHits() 함수를 이용했다. 이 함수를 이용해서 다음 코드를 실행해 보자. 실행한 모든 블럭이 다른 블럭으로 변하게 된다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

time.sleep(60)

hits = mc.events.pollBlockHits()
block = 103

for hit in hits:
    x, y, z = hit.pos.x, hit.pos.y, hit.pos.z
    mc.setBlock(x, y, z, block)

Mission #56: Magic Stairs

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getTilePos()
x, y, z = pos.x, pos.y, pos.z

stairBlock = 53

for step in range(10):
    mc.setBlock(x + step, y + step, z, stairBlock)

Playing Around with range()

다음을 입력해 보자.

>>> aRange = range(5)
>>> list(aRange)
[0, 1, 2, 3, 4]

>>> aRange = range(2, 5)
>>> list(aRange)
[2, 3, 4]

>>> aRange = range(3, 10, 2)
>>> list(aRange)
[3, 5, 7, 9]

>>> newRange = range(100, 0, -2)
>>> list(newRange)
[100, 98, 96, 94, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64,
62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26,
24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2]

10.2 Other List Functions

이번에는 reversed() 라는 함수를 익혀 보자.

>>> backwardsList = reversed(aRange)
>>> list(backwardsList)
[9, 7, 5, 3]


countDown = range(1, 101)
countDown = reversed(countDown)
for item in countDown:
print(item)

Mission #57: Pillars

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


def setPillar(x, y, z, height):
    """Creates a pillar. Args set position and height of pillar"""
    stairBlock = 156
    block = 155

    # Pillar top
    mc.setBlocks(x - 1, y + height, z - 1, x + 1, y + height, z + 1, block, 1)
    mc.setBlock(x - 1, y + height - 1, z, stairBlock, 12)
    mc.setBlock(x + 1, y + height - 1, z, stairBlock, 13)
    mc.setBlock(x, y + height - 1, z + 1, stairBlock, 15)
    mc.setBlock(x, y + height - 1, z - 1, stairBlock, 14)

    # Pillar base
    mc.setBlocks(x - 1, y, z - 1, x + 1, y, z + 1, block, 1)
    mc.setBlock(x - 1, y + 1, z, stairBlock, 0)
    mc.setBlock(x + 1, y + 1, z, stairBlock, 1)
    mc.setBlock(x, y + 1, z + 1, stairBlock, 3)
    mc.setBlock(x, y + 1, z - 1, stairBlock, 2)

    # Pillar column
    mc.setBlocks(x, y, z, x, y + height, z, block, 2)

pos = mc.player.getTilePos()
x, y, z = pos.x + 2, pos.y, pos.z

for xOffset in range(0, 100, 5):
    setPillar(x + xOffset, y, z, 10)

기둥 7개를 그리는 코드이다.

Mission #58: Pyramid

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


block = 24  # sandstone
height = 10
levels = reversed(range(height))

pos = mc.player.getTilePos()
x, y, z = pos.x + height, pos.y, pos.z

for level in levels:
    mc.setBlocks(x - level, y, z - level, x + level, y, z + level, block)
    y += 1

10.3 Looping Over a Dictionary

Dictionary에 사용되는 loop를 살펴보자.

inventory = {'gems': 5, 'potions': 2, 'boxes': 1}
for key in inventory:
print(key)


gems
potions
boxes


inventory = {'gems': 5, 'potions': 2, 'boxes': 1}
for key in inventory:
print(key + " " + str(inventory[key]))

gems 5
potions 2
boxes 1

Mission #59: Scoreboard

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

scores = {}

message = ""

while message != "exit":
    print("Click in the Minecraft window")
    time.sleep(10)
    mc.events.clearAll()

    mc.postToChat("Go")

    time.sleep(60)

    hits = mc.events.pollBlockHits()
    numberOfHits = len(hits)
    mc.postToChat("You used your sword " + hits + " times.")

    playerName = input("Enter your name: ")
    scores[playerName] = numberOfHits

    for name in scores:
        print(name + str(scores[name]))

    message = input("Press enter in this window to start ('exit' to quit)")

10.4 for-else Loops.

for else 구문도 가능하다.

sandwich = ["Bread", "Butter", "Tuna", "Lettuce", "Mayonnaise", "Bread"]
for ingredient in sandwich:
    print(ingredient)
else:
    print("This is the end of the sandwich.")

Bread
Butter
Tuna
Lettuce
Mayonnaise
Bread
This is the end of the sandwich.

Breaking a for-else Loop

다음처럼 break문을 써서 빠져 나올 수 있다.

sandwich = ["Bread", "Butter", "Tuna", "Lettuce", "Mayonnaise", "Bread"]
for ingredient in sandwich:
    if ingredient == "Mayonnaise":
        print("I don't like mayonnaise on my sandwich.")
        break
    else:
        print(ingredient)
else:
    print("This is the end of the sandwich.")

Mission #60: The Diamond Prospector

다음 미션을 수행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getTilePos()
x, y, z = pos.x, pos.y, pos.z

depth = 50

for deep in range(depth):
    block = mc.getBlock(x, y - deep, z)
    if block == 56:
        mc.postToChat("A diamond ore is " + str(deep) + " blocks below you.")
        break
else:
    mc.postToChat("There are no diamond ore blocks below you")

10.5 Nested for Loops and Multidimensional Lists

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
twoDimensionalRainbowList = [[0, 0, 0],
                             [1, 1, 1],
                             [2, 2, 2],
                             [3, 3, 3],
                             [4, 4, 4],
                             [5, 5, 5]]
pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
startingX = x

mc.player.setTilePos(x+3, y, z+3)

for row in twoDimensionalRainbowList:
    for color in row:
        mc.setBlock(x, y, z, 35, color)
        x += 1
    y += 1
    x = startingX

Accessing Values in 2D Lists

1차원 리스트는 다음처럼 하면 된다.

scores = [1, 5, 6, 1]
scores[2] = 7

2차원 이상은 다음처럼 하면 된다.

twoDimensionalRainbowList = [[0, 0, 0],
                             [1, 1, 1},
                             [2, 2, 2],
                             [3, 3, 3],
                             [4, 4, 4],
                             [5, 5, 5]]


twoDimensionalRainbowList[0][1] = 7

Mission #61: Pixel Art

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

pos = mc.player.getTilePos()
x, y, z = pos.x, pos.y, pos.z

mc.player.setTilePos(x+3, y, z+3)

blocks = [[35, 35, 22, 22, 22, 22, 35, 35],
          [35, 22, 35, 35, 35, 35, 22, 35],
          [22, 35, 22, 35, 35, 22, 35, 22],
          [22, 35, 35, 35, 35, 35, 35, 22],
          [22, 35, 22, 35, 35, 22, 35, 22],
          [22, 35, 35, 22, 22, 35, 35, 22],
          [35, 22, 35, 35, 35, 35, 22, 35],
          [35, 35, 22, 22, 22, 22, 35, 35]]

for row in reversed(blocks):
    for block in row:
        mc.setBlock(x, y, z, block)
        x += 1
    y += 1
    x = pos.x

Generating 2D Lists with Loops

다음을 실행해 보자.

import random
    randomNumbers = []
for outer in range(10):
    randomNumbers.append([])
for inner in range(10):
    number = random.randint(1, 4)
randomNumbers[outer].append(number)
print(randomNumbers)


[[3, 1, 4, 1, 4, 1, 2, 3, 2, 2],
[1, 3, 4, 2, 4, 3, 4, 1, 3, 2],
[4, 2, 4, 1, 4, 3, 2, 3, 4, 4],
[1, 4, 3, 4, 3, 4, 3, 3, 4, 4],
[3, 1, 4, 2, 3, 3, 3, 1, 4, 2],
[4, 1, 4, 2, 3, 2, 4, 3, 3, 1],
[2, 4, 2, 1, 2, 1, 4, 2, 4, 3],
[3, 1, 3, 4, 1, 4, 2, 2, 4, 1],
[4, 3, 1, 2, 4, 2, 2, 3, 1, 2],
[3, 1, 3, 3, 1, 3, 1, 4, 1, 2]]

Mission #62: A Weather-Worn Wall

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import random


def brokenBlock():
    brokenBlocks = [48, 67, 4, 4, 4, 4]
    block = random.choice(brokenBlocks)
    return block

pos = mc.player.getTilePos()
x, y, z = pos.x, pos.y, pos.z
mc.player.setTilePos(x+3, y, z+3)
brokenWall = []
height, width = 5, 10

# create the list of broken blocks
for row in range(height):
    brokenWall.append([])
    for column in range(width):
        block = brokenBlock()
        brokenWall[row].append(block)

# set the blocks
for row in brokenWall:
    for block in row:
        mc.setBlock(x, y, z, block)
        x += 1
    y += 1
    x = pos.x

Outputting 3D Lists

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()
pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
mc.player.setTilePos(x+10, y, z+10)

cube = [[[57, 57, 57, 57], [57, 0, 0, 57], [57, 0, 0, 57], [57, 57, 57, 57]],
        [[57, 0, 0, 57], [0, 0, 0, 0], [0, 0, 0, 0], [57, 0, 0, 57]],
        [[57, 0, 0, 57], [0, 0, 0, 0], [0, 0, 0, 0], [57, 0, 0, 57]],
        [[57, 57, 57, 57], [57, 0, 0, 57], [57, 0, 0, 57], [57, 57, 57, 57]]]
startingX = x
startingY = y

for depth in cube:
    for height in reversed(depth):
        for block in height:
            mc.setBlock(x, y, z, block)
            x += 1
        y += 1
        x = startingX
    z += 1
    y = startingY

Accessing Values in 3D Lists

cube = [[[57, 57, 57, 57],
[57, 0, 0, 57],
[57, 0, 0, 57],
[57, 57, 57, 57]],
#
[[57, 0, 0, 57],
[0, 0, 0, 0],
[0, 0, 0, 0],
[57, 0, 0, 57]],
#
[[57, 0, 0, 57],
[0, 0, 0, 0],
[0, 0, 0, 0],
[57, 0, 0, 57]],
#
[[57, 57, 57, 57],
[57, 0, 0, 57],
[57, 0, 0, 57],
[57, 57, 57, 57]]]

cube[0] 이면

[[57, 57, 57, 57],
[57, 0, 0, 57],
[57, 0, 0, 57],
[57, 57, 57, 57]]

cube[0][3]

[57, 57, 57, 57]

cube[0][3][3] = 41 처럼 변경할 수 있다.

Mission #63: Duplicate a Building

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


def sortPair(val1, val2):
    if val1 > val2:
        return val2, val1
    else:
        return val1, val2


def copyStructure(x1, y1, z1, x2, y2, z2):
    x1, x2 = sortPair(x1, x2)
    y1, y2 = sortPair(y1, y2)
    z1, z2 = sortPair(z1, z2)

    width = x2 - x1
    height = y2 - y1
    length = z2 - z1

    structure = []

    print("Please wait...")

    # Copy the structure
    for row in range(height):
        structure.append([])
        for column in range(width):
            structure[row].append([])
            for depth in range(length):
                block = mc.getBlock(x1 + column, y1 + row, z1 + depth)
                structure[row][column].append(block)

    return structure


def buildStructure(x, y, z, structure):
    xStart = x
    yStart = y
    for row in structure:
        for column in row:
            for block in column:
                mc.setBlock(x, y, z, block)
                z += 1
            x += 1
            z = yStart
        y += 1
        x = xStart


# get the position of the first corner
input("Move to the first corner and press enter in this window")
pos = mc.player.getTilePos()
x1, y1, z1 = pos.x, pos.y, pos.z

# get the position of the second corner
input("Move to the opposite corner and press enter in this window")
pos = mc.player.getTilePos()
x2, y2, z2 = pos.x, pos.y, pos.z

# copy the building
structure = copyStructure(x1, y1, z1, x2, y2, z2)

# get the position for the copy
input("Move to the position you want to create the structure and press ENTER in this window")
pos = mc.player.getTilePos()
x, y, z = pos.x, pos.y, pos.z
buildStructure(x, y, z, structure)

10.6 What You Learned

for loops with lists range() function more about for loops lists, such as reversing lists, looping over dictionaries, and breaking for loops

two- and threedimensional lists with nested loops

chapter 11: Saving and Loading Buildings with Files and Modules

이 장에서는 데이터를 저장하는 파일에 대해서 배워보도록 하겠다.

11.1 Using Files

Opening a File

파일은 다음 형식으로 열고 닫는다.

secretFile = open("secretFile.txt", "w")

w는 쓰기전용이다. r 읽기전용 r+ 읽기+쓰기 a 추가

Writing to and Saving a File

파일을 열어서 쓰고 저장은 다음처럼 한다.

secretFile = open("secretFile.txt", "w")
secretFile.write("This is a secret file. Shhh! Don't tell anyone.")
secretFile.close()

Reading a File

파일은 다음처럼 읽는다.

secretFile = open("secretfile.txt", "r")
print(secretFile.read())
secretFile.close()

Reading a Line of a File

readline() function 을 사용하면 한줄씩 읽게 된다.

예를 들어 파일에 “CoolnDancenParty” 로 되어 있으면 Cool Dance Party

이런식으로 읽히게 된다.

Mission #64: To-Do List

11.2 Using Modules

toDoList.txt

Test
test
test

파일에 입력을 하고

toDoFile = open("toDoList.txt", "w")

toDoList = ""

toDoItem = input("Enter a to do list item: ")

while toDoItem != "exit":
    toDoList = toDoList + toDoItem + " \n"
    toDoItem = input("Enter a to do list item: ")

toDoFile.write(toDoList)
toDoFile.close()

그 화일을 읽는 연습이다.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

toDoList = open("toDoList.txt", "r")

for line in toDoList:
    mc.postToChat(line)

Using Modules

Modules are collections of functions

Python standard library

The pickle Module

다음처럼 사용한다.

import pickle
locations = {'John': 'Forest', 'Phillipa': 'Mountains', 'Pete': 'City'}
secretFile= open("secretFile.txt", "wb")
pickle.dump(locations, secretFile)

import pickle
secretFile= open("secretFile.txt", "rb")
locations = pickle.load(secretFile)

Importing One Function with the from Clause

모듈에서 함수 하나만을 쓸수 있다.

from pickle import dump
locations = {'John': 'Forest', 'Phillipa': 'Mountains', 'Pete': 'City'}
secretFile= open("secretFile", "wb")
dump(locations, secretFile)

from pickle import dump, load
locations = {'John': 'Forest', 'Phillipa': 'Mountains', 'Pete': 'City'}
secretFile= open("secretFile", "wb")
dump(locations, secretFile)
locations = load(secretFile)
print(locations['Phillipa'])

Importing All Functions with *

*를 사용하면 모든 함수를 로딩하게 된다. *를 쓰면 편하긴 한데 여러 모듈을 한꺼번에 쓰면 동일 함수명을 쓰는것에 충돌을 가져올 수 있다. 그래서 *를 지양하고 특정 함수를 쓰는것을 권장한다. 모듈내 함수가 어떤것인지 몰라 테스트용으로 쓸때 권장한다.

Giving a Module a Nickname

모듈을 로딩해서 특정 이름으로 할당할 수 있다.

import pickle as p
p.dump(locations, secretFile)

Mission #65: Save a Building

한쪽맵에서 빌딩을 저장한 파일을 다른쪽에 옮기는 미션이다.

Part 1: Saving the Building

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import pickle


def sortPair(val1, val2):
    if val1 > val2:
        return val2, val1
    else:
        return val1, val2


def copyStructure(x1, y1, z1, x2, y2, z2):
    x1, x2 = sortPair(x1, x2)
    y1, y2 = sortPair(y1, y2)
    z1, z2 = sortPair(z1, z2)

    width = x2 - x1
    height = y2 - y1
    length = z2 - z1

    structure = []

    print("Please wait...")

    # Copy the structure
    for row in range(height):
        structure.append([])
        for column in range(width):
            structure[row].append([])
            for depth in range(length):
                block = mc.getBlockWithData(x1 + column, y1 + row, z1 + depth)
                structure[row][column].append(block)

    return structure

input("Move to the first position and press ENTER in this window")
pos1 = mc.player.getTilePos()

# get the position of the first corner
x1 = pos1.x
y1 = pos1.y
z1 = pos1.z

input("Move to the opposite corner and press ENTER in this window")
pos2 = mc.player.getTilePos()

# get the position of the second corner
x2 = pos2.x
y2 = pos2.y
z2 = pos2.z

structure = copyStructure(x1, y1, z1, x2, y2, z2)

# store the structure in a file
pickleFile = open("pickleFile", "wb")
pickle.dump(structure, pickleFile)

Part 2: Loading the Building

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import pickle


def buildStructure(x, y, z, structure):
    xStart = x
    zStart = z
    for row in structure:
        for column in row:
            for block in column:
                mc.setBlock(x, y, z, block.id, block.data)
                z += 1
            x += 1
            z = zStart
        y += 1
        x = xStart


pickleFile = open("pickleFile", "rb")
structure = pickle.load(pickleFile)
pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

buildStructure(x, y, z, structure)

건물을 다시 만드는 코드이다.

11.3 Storing Lots of Data with the shelve Module

pickle은 한번에 한 데이터만 저장할 수 있지만 어떤 프로그램들은 여러 종류의 변수를 넣을 필요가 있다. 여러 데이터를 쓰게 되면 각각 파일을 만들어야 되고 관리도 복잡해지고 힘들다. 파이썬에서는 shelve 모듈을 제공한다. 이것은 한 파일에 여러개의 데이터를 저장할때 쓰인다.

import shelve
shelveFile = shelve.open(“locationsFile.db”)

Opening a File with shelve

사용법은 다음과 같다.

import shelve
shelveFile = shelve.open("locationsFile.db")

Adding, Modifying, and Accessing Items with shelve

수정은 다음과 같이 한다.

import shelve
shelveFile = shelve.open("locationsFile.db")
shelveFile['Beatrice'] = 'Submarine'
shelveFile.close()

Mission #66: Save a Collection of Structures

이전에 저장했던 데이터를 pickle 말고 shelve로 저장하는 미션이다.

Part 1: Saving a Structure to a Collection

저장했던 파일을 collection어 넣어 보도록 하자.

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import shelve


def sortPair(val1, val2):
    if val1 > val2:
        return val2, val1
    else:
        return val1, val2


def copyStructure(x1, y1, z1, x2, y2, z2):
    x1, x2 = sortPair(x1, x2)
    y1, y2 = sortPair(y1, y2)
    z1, z2 = sortPair(z1, z2)

    width = x2 - x1
    height = y2 - y1
    length = z2 - z1

    structure = []

    print("Please wait...")

    # Copy the structure
    for row in range(height):
        structure.append([])
        for column in range(width):
            structure[row].append([])
            for depth in range(length):
                block = mc.getBlockWithData(x1 + column, y1 + row, z1 + depth)
                structure[row][column].append(block)

    return structure

input("Move to the first position and press ENTER in this window")
pos1 = mc.player.getTilePos()

# get the position of the first corner
x1 = pos1.x
y1 = pos1.y
z1 = pos1.z

input("Move to the opposite corner and press ENTER in this window")
pos2 = mc.player.getTilePos()

# get the position of the second corner
x2 = pos2.x
y2 = pos2.y
z2 = pos2.z

structure = copyStructure(x1, y1, z1, x2, y2, z2)

# name the structure
structureName = input('What do you want to call the structure? ')

# store the structure in a file
shelveFile = shelve.open("shelveFile.db")
shelveFile[structureName] = structure
shelveFile.close()

Part 2: Loading a Structure from a Collection

다음 코드를 실행해 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import shelve


def buildStructure(x, y, z, structure):
    xStart = x
    zStart = z
    for row in structure:
        for column in row:
            for block in column:
                mc.setBlock(x, y, z, block.id, block.data)
                z += 1
            x += 1
            z = zStart
        y += 1
        x = xStart


structureDictionary = shelve.open("shelveFile.db")

structureName = input("Enter the structure's name ")

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

buildStructure(x, y, z, structureDictionary[structureName])

11.4 Installing New Modules with pip

파이썬은 기본 모듈 이외에도 많은 모듈들이 존재한다. 기본적으로 pip을 이용해서 이런 모듈을 인스톨 한다. 최근의 python 3버젼은 pip이 내장되어 있다. 없는 경우는 pip 모듈을 인스톨 해야 한다.

사용법은 다음과 같다.

pip install Flask

11.5 Using a Module from pip: Flask

다음 코드를 실행해 보자. 간단한 웹서버를 구성해 보자.

from flask import Flask
app = Flask(__name__)
@app.route("/")
def showName():
    return "Craig Richardson"
app.run()

Mission #67: Position Website

player의 위치를 Flask 웹 페이지에 뿌려주는 프로그램이다.

skip this contents

11.6 What You Learned

how to read and write to files using Python’s standard library

giving you control over files when you create your own programs.

use modules, which extend Python’s capabilities

chapter 12: Getting Classy with Object-Oriented Programming

객체지향 프로그램에 대해서 알아본다 . OOP(Object-Oriented-Programming) 객체지향 프로그램은 모든 사물을 객체로 보고 각각 기능과 변수들을 정의 하고 쓰는 개념이다. 그렇게 정의된 함수나 변수들의 집단을 Class라고 정의 하고 이 함수나 변수들을 재사용하는게 가장 중요한 요소가 된다. class에서 쓰이는 fuction을 method라고 한다. 그리고 변수들을 attribute라고 한다. OOP의 특성이나 기능들은 차차 알아보도록 하자.

12.1 Object-Oriented Basics

파이썬에서 클래스는 다음과 같이 정의한다.

class ClassName(object):
    def __init__(self):
        # Body of init

12.2 Creating a Class

다음의 클래스를 만들어 보자.

class Cat(object):
    owner = "Craig"
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
    def eat(self, food):
        self.weight = self.weight + 0.05
        print(self.name + " is eating " + food)
    def eatAndSleep(self, food):
        self.eat(food)
        print(self.name + " is now sleeping...")
    def getWeightInGrams(self):
        return self.weight * 1000

fluff = Cat("Fluff", 4.5)  # Object 생성
print(fluff.owner)

stella = Cat("Stella", 3.9)  # Object 생성
print(stella.owner)           # Accessing Attributes
print(fluff.weight)           #Accessing Attributes

fluff.eat("tuna")
fluff.eatAndSleep("tuna")

print(fluff.getWeightInGrams())
print(fluff.name)
print(stella.name)

fluff.eat("tuna")
stella.eat("cake")
stella.owner = "Matthew"

print(stella.owner)
print(fluff.owner)

Mission #68: Location Objects

위치 이동하는 클래스를 만들어 보자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

class Location(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z


bedroom = Location(64, 52, -8)
mc.player.setTilePos(bedroom.x, bedroom.y, bedroom.z)

12.3 Understanding Methods

Mission #69: Ghost House

다음 미션을 알아보도록 하자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

class Building(object):
    def __init__(self, x, y, z, width, height, depth):
        self.x = x
        self.y = y
        self.z = z

        self.width = width
        self.height = height
        self.depth = depth

    def build(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 4)

        mc.setBlocks(self.x + 1, self.y + 1, self.z + 1,
                     self.x + self.width - 1, self.y + self.height - 1, self.z + self.depth - 1, 0)

        self.buildWindows()
        self.buildDoor()

    def clear(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 0)

    def buildWindows(self):
        mc.setBlock(self.x + (self.width / 4 * 3), self.y + 2, self.z, 0)
        mc.setBlock(self.x + (self.width / 4), self.y + 2, self.z, 0)

    def buildDoor(self):
        mc.setBlocks(self.x + (self.width / 2), self.y + 1, self.z, self.x + (self.width / 2), self.y + 2, self.z, 0)


pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
ghostHouse = Building(x, y, z, 10, 6, 8)
ghostHouse.build()

time.sleep(30)

ghostHouse.clear()
ghostHouse.x = 8

12.4 Returning Values with Methods

당연히 Function에서 배웠듯이 리턴값을 반환한다.

Mission #70: Ghost Castle

다음 미션을 수행해 보도록 하자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time


class NamedBuilding(object):
    def __init__(self, x, y, z, width, height, depth, name):
        self.x = x
        self.y = y
        self.z = z

        self.width = width
        self.height = height
        self.depth = depth

        self.name = name

    def build(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 4)

        mc.setBlocks(self.x + 1, self.y + 1, self.z + 1,
                     self.x + self.width - 1, self.y + self.height - 1, self.z + self.depth - 1, 0)

        self.buildWindows()
        self.buildDoor()

    def clear(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 0)

    def getInfo(self):
        return self.name + "'s location is at " + str(self.x) + ", " + str(self.y) + ", " + str(self.z)

    def buildWindows(self):
        mc.setBlock(self.x + (self.width / 4 * 3), self.y + 2, self.z, 0)
        mc.setBlock(self.x + (self.width / 4), self.y + 2, self.z, 0)

    def buildDoor(self):
        mc.setBlocks(self.x + (self.width / 2), self.y + 1, self.z, self.x + (self.width / 2), self.y + 2, self.z, 0)


pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

ghostCastle = NamedBuilding(x, y, z, 10, 16, 16, "Ghost Castle")
ghostCastle.build()
mc.postToChat(ghostCastle.getInfo())

time.sleep(30)

ghostCastle.clear()

12.5 Creating Multiple Objects

class안에는 여러개 object를 생성할 수 있다.

Mission #71: Ghost Town

다음 미션을 수행해 보도록 하자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time

class Building(object):
    def __init__(self, x, y, z, width, height, depth):
        self.x = x
        self.y = y
        self.z = z

        self.width = width
        self.height = height
        self.depth = depth

    def build(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 4)

        mc.setBlocks(self.x + 1, self.y + 1, self.z + 1,
                     self.x + self.width - 1, self.y + self.height - 1, self.z + self.depth - 1, 0)

        self.buildWindows()
        self.buildDoor()

    def clear(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 0)

    def buildWindows(self):
        mc.setBlock(self.x + (self.width / 4 * 3), self.y + 2, self.z, 0)
        mc.setBlock(self.x + (self.width / 4), self.y + 2, self.z, 0)

    def buildDoor(self):
        mc.setBlocks(self.x + (self.width / 2), self.y + 1, self.z, self.x + (self.width / 2), self.y + 2, self.z, 0)


pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z
ghostHouse = Building(x, y, z, 10, 6, 8)
ghostHouse.build()

time.sleep(30)

ghostHouse.clear()
ghostHouse.x = 8

다음은 마을을 형성하는 코드이다.

import time

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


class Building(object):
    def __init__(self, x, y, z, width, height, depth):
        self.x = x
        self.y = y
        self.z = z

        self.width = width
        self.height = height
        self.depth = depth

    def build(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 4)

        mc.setBlocks(self.x + 1, self.y + 1, self.z + 1,
                     self.x + self.width - 1, self.y + self.height - 1, self.z + self.depth - 1, 0)

        self.buildWindows()
        self.buildDoor()

    def clear(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 0)

    def buildWindows(self):
        mc.setBlock(self.x + (self.width / 4 * 3), self.y + 2, self.z, 0)
        mc.setBlock(self.x + (self.width / 4), self.y + 2, self.z, 0)

    def buildDoor(self):
        mc.setBlocks(self.x + (self.width / 2), self.y + 1, self.z, self.x + (self.width / 2), self.y + 2, self.z, 0)


pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

ghostHouse = Building(x, y, z, 10, 6, 8)
shop = Building(x + 12, y, z, 8, 12, 10)
hospital = Building(x + 25, y, z - 1, 30, 40, 30)
bakery = Building(x - 12, y - 5, z, 9, 11, 13)


ghostHouse.build()
shop.build()
hospital.build()
bakery.build()

time.sleep(30)

ghostHouse.clear()
shop.clear()
hospital.clear()
bakery.clear()

12.6 Class Attributes

When multiple objects share the same attribute, it’s called a class attribute.

12.7 Understanding Inheritance

OOP의 가장 큰 특징중에 하나가 상속성이다. 상위 클래스를 받아서 하위 클래스를 생성하면 상위 클래스 매쏘드나 머트리붓을 모두 갖는 특징을 갖는다. 그림으로 보면 다음과 같다. superclass <->subclass 관계이다.

./img/chapter12-5.png

Inheriting a Class

Class 상속은 다음과 같이 쓰인다.

class Bird(object):
    def __init__(self, name, wingspan):
        self.name = name
        self.wingspan = wingspan
    def birdcall(self):
        print("chirp")
    def fly(self):
        print("flap")
class Penguin(Bird):
    def swim(self):
        print("swimming")
    def birdcall(self):
        print("sort of a quack")
    def fly(self):
        print("Penguins cannot fly :(")
class Parrot(Bird):
    def __init__(self, name, wingspan, color):
        self.name = name
        self.wingspan = wingspan
        self.color = color

gardenBird = Bird("Geoffrey", 12)
gardenBird.birdcall()
gardenBird.fly()
sarahThePenguin = Penguin("Sarah", 10)
sarahThePenguin.swim()
sarahThePenguin.fly()
sarahThePenguin.birdcall()
freddieTheParrot = Parrot("Freddie", 12, "blue")

print(freddieTheParrot.color)
freddieTheParrot.fly()
freddieTheParrot.birdcall()

Mission #72: Ghost Hotel

다음 미션을 수행해 보도록 하자.

from mcpi.minecraft import Minecraft
mc = Minecraft.create()

import time


class Building(object):
    def __init__(self, x, y, z, width, height, depth):
        self.x = x
        self.y = y
        self.z = z

        self.width = width
        self.height = height
        self.depth = depth

    def build(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 4)

        mc.setBlocks(self.x + 1, self.y + 1, self.z + 1,
                     self.x + self.width - 1, self.y + self.height - 1, self.z + self.depth - 1, 0)

        self.buildWindows()
        self.buildDoor()

    def clear(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 0)

    def buildWindows(self):
        mc.setBlock(self.x + (self.width / 4 * 3), self.y + 2, self.z, 0)
        mc.setBlock(self.x + (self.width / 4), self.y + 2, self.z, 0)

    def buildDoor(self):
        mc.setBlocks(self.x + (self.width / 2), self.y + 1, self.z, self.x + (self.width / 2), self.y + 2, self.z, 0)


class FancyBuilding(Building):
    def upgrade(self):
        # carpet
        mc.setBlocks(self.x + 1, self.y, self.z + 1,
                     self.x + self.width - 1, self.y, self.z + self.depth - 1,
                     35, 6)

        # flowers
        mc.setBlocks(self.x - 1, self.y, self.z - 1,
                     self.x - 1, self.y, self.z + self.depth + 1,
                     37)
        mc.setBlocks(self.x - 1, self.y, self.z - 1,
                     self.x + self.width + 1, self.y, self.z - 1,
                     37)
        mc.setBlocks(self.x + self.width + 1, self.y, self.z - 1,
                     self.x + self.width + 1, self.y, self.z + self.depth + 1,
                     37)
        mc.setBlocks(self.x - 1, self.y, self.z + self.depth + 1,
                     self.x + self.width + 1, self.y, self.z + self.depth + 1,
                     37)


pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

ghostHotel = FancyBuilding(x, y, z, 10, 6, 8)
ghostHotel.build()
ghostHotel.upgrade()

time.sleep(30)

ghostHotel.clear()

12.8 Overriding Methods and Attributes

subclass에서 superclass에서 정의한 method를 다시 정의할 수 있다.

다음 미션을 수행해 보자.

Mission #73: Ghost Tree

import time

from mcpi.minecraft import Minecraft
mc = Minecraft.create()


class Building(object):
    def __init__(self, x, y, z, width, height, depth):
        self.x = x
        self.y = y
        self.z = z

        self.width = width
        self.height = height
        self.depth = depth

    def build(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 4)

        mc.setBlocks(self.x + 1, self.y + 1, self.z + 1,
                     self.x + self.width - 1, self.y + self.height - 1, self.z + self.depth - 1, 0)

        self.buildWindows()
        self.buildDoor()

    def clear(self):
        mc.setBlocks(self.x, self.y, self.z,
                     self.x + self.width, self.y + self.height, self.z + self.depth, 0)

    def buildWindows(self):
        mc.setBlock(self.x + (self.width / 4 * 3), self.y + 2, self.z, 0)
        mc.setBlock(self.x + (self.width / 4), self.y + 2, self.z, 0)

    def buildDoor(self):
        mc.setBlocks(self.x + (self.width / 2), self.y + 1, self.z, self.x + (self.width / 2), self.y + 2, self.z, 0)


class Tree(Building):
    def build(self):
        """Creates a tree at the coordinates given"""
        wood = 17
        leaves = 18

        # trunk
        mc.setBlocks(self.x, self.y, self.z, self.x, self.y + 5, self.z, wood)

        # leaves
        mc.setBlocks(self.x - 2, self.y + 6, self.z - 2, self.x + 2, self.y + 6, self.z + 2, leaves)
        mc.setBlocks(self.x - 1, self.y + 7, self.z - 1, self.x + 1, self.y + 7, self.z + 1, leaves)

    def clear(self):
        """Clears a tree at the coordinates given"""
        wood = 0
        leaves = 0

        # trunk
        mc.setBlocks(self.x, self.y, self.z, self.x, self.y + 5, self.z, wood)

        # leaves
        mc.setBlocks(self.x - 2, self.y + 6, self.z - 2, self.x + 2, self.y + 6, self.z + 2, leaves)
        mc.setBlocks(self.x - 1, self.y + 7, self.z - 1, self.x + 1, self.y + 7, self.z + 1, leaves)

pos = mc.player.getTilePos()
x = pos.x
y = pos.y
z = pos.z

ghostTree = Tree(x, y, z, 10, 6, 8)
ghostTree.build()

time.sleep(10)

ghostTree.clear()

12.9 What You Learned

object-oriented programming

class and create objects

inheritance