1. VSCode에서 Python 확장을 설치한다.


2. "Linter pylint is not installed" 문구 나오면, pylint를 설치해준다.(아래 경우는 리눅스일 때) 

/usr/bin/python3 -m pip install -U pylint --user


3. 디버그 체크시 문제가 없음에도 불구하고 오류를 체크할 경우, settings.json에 python.linting.enabled이나 python.linting.pylintEnabled를 false를 한다.

"python.linting.enabled": false 혹은 "python.linting.pylintEnabled": false



<참고>

https://stackoverflow.com/questions/43272664/linter-pylint-is-not-installed

# -*- coding: utf-8 -*-

import sys
import os
import io
import zipfile
import mmap

if __name__ == "__main__":
	with open("zip 파일"), "r+b") as zf:
		zip_file = zf.read()
	memory_map = mmap.mmap(-1, len(zip_file))
	memory_map.write(zip_file)
	zip_file_data = zipfile.ZipFile(memory_map)

	"""
	여기에 zip 파일을 처리할 코드를
	작성한다.
	
	"""
	
	zip_file_data.close()
	memory_map.close()

<참고>
https://docs.python.org/3.6/library/mmap.html
http://barambunda.tistory.com/12
https://docs.python.org/3.6/library/zipfile.html

1.기본

class Test:
    __name = "John"

    def get_name(self):
        return self.__name
    
    def set_name(self, value):
        self.__name = value

if __name__ == "__main__":
    t = Test()
    print(t.get_name())
    t.set_name("David")
    print(t.get_name())

 

2. property 사용

class Test:
    __name = "John"

    def get_name(self):
        return self.__name
    
    def set_name(self, value):
        self.__name = value

    name = property(get_name, set_name)

if __name__ == "__main__":
    t = Test()
    print(t.name)
    t.name = "David"
    print(t.name)

 

3. @property(데코레이터:Decorator) 사용

class Test:
    __name = "John"

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, value):
        self.__name = value

if __name__ == "__main__":
    t = Test()
    print(t.name)
    t.name = "David"
    print(t.name)

 

4. 여러 속성에 대해서 동일하게 처리해야할 경우, @property를 사용하면 코드가 지저분해지므로, Descriptor를 하면 코드가 깔끔하게 정리됨.

class T:
    __name = ""

    def __get__(self, instance, owner):
        return getattr(instance, "__name")

    def __set__(self, instance, value):
        setattr(instance, "__name", value)

class Test:
    name = T()

if __name__ == "__main__":
    t = Test()
    t1 = Test()
    t2 = Test()
    t.name = "David"
    t1.age = 40
    t2.address = "Korea"
    print(t.name, t1.age, t2.address)

 

<참고>
https://docs.python.org/3/howto/descriptor.html

Python은 접근제어를 하기 위해서 키워드를 제공하지 않는 대신에 명명법(Naming)에 의한 방법으로 설정 가능.


<Public>

    • _(Single underscore)를 접두사로 사용하지 않음.(ex: name)
    • Python의 모든 속성 및 메소드는 기본적으로 public.
    • 외부 클래스에서 접근 가능.

<Protected>

    • _를 접두사로 사용. (ex: _name)
    • 해당 및 하위 클래스에서만 접근 가능.

<Private>

    • __(Double underscore)를 접두사로 사용.(ex: __name)
    • 해당 클래스 이외에는 접근 불가능.(단, Property Get, Set을 이용하면 접근가능)

※Protected와 Private에서 _를 접미사로 사용할 경우, 한개는 허용하지만, 두개 이상이면 Public으로 간주함.

    • _name_은 Protected, _name__은 Public으로 간주.


<조건>

-CA(Cellular Automata)를 이용하여 동굴형태의 던전맵을 생성.

-0세대(랜덤생성맵) Wall의 생성 비율은 45%, 5세대까지 Loop.

-경계면도 Rule 적용.

-Rule은 B5678/S45678

-Moore neighborhood 검색방식.

 

<결과 예제: 40x20 크기로 5세대까지 Loop>

 

<소스코드>

# -*- coding: utf-8 -*-
#
#	cave_map_generator.py
#
#	http://codememo.tistory.com
#
#	# - Wall / Space - Empty, CA Rule - B5678/S45678
#

import sys
import os
import random

class Map:
	
	wall_ratio = 45
	
	def __init__(self, column, row):
		self.column, self.row = column, row
		self.wall, self.empty = 0, 0
		self.map = [["#"] * self.row for m in range(self.column)]
		self.new_map = [["#"] * self.row for m in range(self.column)]

		for column in range(self.column):
			for row in range(self.row):
				if (0< row < self.row - 1) and (0 < column < self.column - 1):
					if (random.random() * 100) < self.wall_ratio:
						self.map[column][row] = "#"
					else:
						self.map[column][row] = " "
					
					self.new_map[column][row] = " "
		
		print("0 Generation")
		self.result()
		
	def generate(self, count):
		for i in range(1, count + 1):
			for column in range(1, self.column - 1):
				for row in range(1, self.row -1):
					self.check(column, row)

			print("%d Generation" % (i))
			self.map = self.new_map
			self.result()
			
			self.new_map = [["#"] * self.row for m in range(self.column)]

			for m in range(1, self.column - 1):
				for n in range(1, self.row - 1):
					self.new_map[m][n] = " "

	def check(self, column, row):

		neighborhood_empty, neighborhood_wall = 0, 0
		
		for m in range(-1, 2):
			for n in range(-1, 2):
				if m != 0 or n != 0:
					if self.map[column + m][row + n] == "#":
						neighborhood_wall += 1
					elif self.map[column + m][row + n] == " ":
						neighborhood_empty += 1					

		if ((self.map[column][row] == "#" and neighborhood_wall >= 4) or
				(self.map[column][row] == " " and neighborhood_wall >= 5)):
			self.new_map[column][row] = "#"
		else:
			self.new_map[column][row] = " "

	def result(self):
		dungeon = ""
		self.wall, self.empty = 0, 0
		
		for column in range(self.column):
			for row in range(self.row):
				dungeon += self.map[column][row]
				if self.map[column][row] == "#":
					self.wall += 1
				else:
					self.empty += 1
			
			if column < (self.column - 1):
				dungeon += "\n"
		
		print("Wall : %d Empty: %d" % (self.wall, self.empty))
		print(dungeon)

def main():
	map = Map(20, 40)
	map.generate(5)
	
	sys.exit()
	
if __name__ == "__main__":
	main()

 

<참고>

http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels

pygame.sprite.spritecollide(sprite, group, dokillsprite, group, dokill, collided = None)

pygame.sprite.groupcollide(group1, group2, dokill1, dokill2, collided = None)

pygame.sprite.spritecollideany(sprite, group, colided = None)


위의 함수 사용시 충돌 거리 비율울 조절하고자 할 때는 collided에 아래 함수 중 하나를 사용하면 된다.


pygame.sprite.collide_rect_ratio(ratio)

pygame.sprite.collide_circle_ratio(ratio)



<참고>

https://www.pygame.org/docs/ref/sprite.html

<증상>

1. Python 인터프리터로 실행하면 정상적으로 작동하지만, Pyinstaller로 컴파일 하면 에러 발생.

2. "-*- coding: utf-8 -*-"을 사용하였으나 무용지물.

 

<해결책>

1. 문제가 되는 소스 코드를 UTF-8로 변환하여 저장한 후 컴파일함.

 

pytmx를 이용하여 tmx파일 읽어오기

asset은 Tiled 프로그램내의 샘플을 이용(http://www.mapeditor.org)

 

<실행화면>

 

<소스코드>

# -*- coding: utf-8 -*-
#
#	tmx_file_load.py
#	coding with python 3.5.3
#
#	http://codememo.tistory.com
#

import sys
import os
import pygame
import pytmx

pygame.init()
display = pygame.display.set_mode((512, 368))
pygame.display.set_caption("tmx file load")

tmx_data = pytmx.load_pygame("smw_background.tmx")

clock = pygame.time.Clock()

running = True

while running:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			pygame.quit()
			sys.exit()

		if event.type == pygame.KEYDOWN:
			if event.key == pygame.K_ESCAPE:
				running = False
	
	display.fill((0, 96, 184))
	
	for layer in tmx_data.visible_layers:
		for x, y, gid, in layer:
			tile = tmx_data.get_tile_image_by_gid(gid)
			if tile:
				display.blit(tile, (x * tmx_data.tilewidth, y * tmx_data.tileheight))

	pygame.display.update()
	clock.tick(60)

 

<첨부파일>

tmx_file_load.zip

 

+ Recent posts