一、图片转字符画
import math
from PIL import Image
import numpy as np
#定义字符映射,从最暗到最亮
chars = '@%#*+=-:.'
def img_to_ascii(image_path,new_width=100):
#打开图片
img = Image.open(image_path)
#计算新的高度(保持图片的纵横比) 由于字符通常比高宽比1:1的像素稍微窄一些,调整高度可以补偿这种比例差异,从而使最终的字符画在视觉上更接近原图。
aspect_ratio = img.height / img.width
new_height = int(new_width * aspect_ratio)
#调整图片大小
img = img.resize((new_width, new_height))
#转换为灰度图(将图像转换为灰度图是因为字符画只需要处理图像的亮度信息,而不关心颜色。灰度图将每个像素表示为一个亮度值(从黑到白),简化了图像的数据,使其更容易映射到字符集。这样可以根据像素的亮度选择合适的字符来表示图像的不同区域,实现更清晰的字符画效果。)
img = img.convert('L')
#获取像素数据映射到字符
pixels = np.array(img) #np.array 可以将不同格式的数据(例如:图像、列表、元组等)转换为numpy数组 在图像处理中通常使用numpy数组来表示图像数据
#将像素数据映射到字符
ascii_str = ''
try:
for row in pixels:
for pixel in row:
# ascii_str += chars[pixel // 25] # 25是256/10 用于将每个灰度值映射到相应的字符。pixel 是图像中每个像素的灰度值(0到255之间),25 是将灰度值划分成10个字符区间的结果(因为256/10 ≈ 25)。所以 pixel // 25 将灰度值转化为0到9的索引,映射到 chars 字符集中对应的位置,从而生成ASCII艺术。
ascii_str += chars[min(pixel // 25, len(chars) - 1)] # 25 是 256/10 保证不超出字符串的范围
ascii_str += '\n'
except:
print(pixel)
return ascii_str
if __name__ == '__main__':
# 使用示例
ascii_art = img_to_ascii("./data/素材3.png", new_width=100)
print(ascii_art)
二、200行代码实现2048
import random
import os
import sys
import time
#游戏配置
SIZE = 4
WIN_VALUE = 2048
#初始化游戏板
def init_board():
board = [[0]*SIZE for _ in range(SIZE)]
add_random(board)
add_random(board)
return board
#在板上添加一个随机值(2或4)
def add_random(board):
empty_cells = [(r,c) for r in range(SIZE) for c in range(SIZE) if board[r][c] == 0]
if empty_cells:
r,c = random.choice(empty_cells) #随机选择一个元素 r,c代表被选择的元素的行和列
board[r][c] = 4 if random.random() < 0.1 else 2 #需要随机生成2或4
#打印游戏板
def print_board(board):
#清屏
'''
os.system:这个函数用来在系统的命令行或终端中执行指定的命令。os.name:这是一个 Python 属性,用来返回当前操作系统的名称。
os.name 的值可以是 'posix'、'nt'、'os2' 等。对于 Windows 操作系统,os.name 的值是 'nt';对于大多数 Unix-like 系统(如 Linux 和 macOS),os.name 的值是 'posix'。
'cls' 和 'clear':
'cls':这是 Windows 操作系统中的命令,用来清除命令提示符窗口中的内容。
'clear':这是 Unix-like 操作系统(如 Linux 和 macOS)中的命令,用来清除终端窗口中的内容。
'''
os.system('cls' if os.name == 'nt' else 'clear')
for row in board:
print('\t'.join(str(cell) if cell != 0 else '.' for cell in row))
print()
#合并行
def merge_line(line):
non_zero = [i for i in line if i != 0]
merged = []
skip = False
for i in range(len(non_zero)):
if skip:
skip = False
continue
if i < len(non_zero) - 1 and non_zero[i] == non_zero[i+1]:
merged.append(non_zero[i] * 2)
skip = True
else:
merged.append(non_zero[i])
return merged + [0] * (SIZE - len(merged))
#旋转板
def rotate_board(board):
'''
zip 函数用于将多个可迭代对象(如列表、元组)中的元素按位置配对,生成一个元组的迭代器。每个元组包含来自每个输入可迭代对象的对应元素。
a = [1, 2, 3]
b = ['a', 'b', 'c']
zipped = zip(a, b)
print(list(zipped)) # 输出:[(1, 'a'), (2, 'b'), (3, 'c')]
board[::-1]:
这是一个切片操作,用于将 board 列表反转。[::-1] 表示将列表从最后一个元素到第一个元素倒序排列。
对于这个board来讲是将行倒序
* 操作符用于将 board[::-1] 的元素解包成独立的参数传递给 zip 函数。
'''
return [list(row) for row in zip(*board[::-1])]
# 移动和合并板
def move_left(board):
for i in range(SIZE):
board[i] = merge_line(board[i])
return board
def move_right(board):
for i in range(SIZE):
board[i] = merge_line(board[i][::-1])[::-1]
return board
def move_up(board):
board = rotate_board(board)
board = move_left(board)
return rotate_board(board[::-1])
def move_down(board):
board = rotate_board(board)
board = move_right(board)
return rotate_board(board[::-1])
# 检查是否还有可能移动的空格或合并
def can_move(board):
for i in range(SIZE):
for j in range(SIZE - 1):
if board[i][j] == 0 or board[i][j] == board[i][j + 1]:
return True
for j in range(SIZE - 1):
if board[j][i] == 0 or board[j][i] == board[j + 1][i]:
return True
return False
# 检查是否游戏胜利
def check_win(board):
return any(cell == WIN_VALUE for row in board for cell in row)
# 主游戏循环
def main():
board = init_board()
while True:
print_board(board)
if check_win(board):
print("Congratulations! You've reached 2048!")
break
if not can_move(board):
print("Game Over! No moves left.")
break
move = input("Use 'W', 'A', 'S', 'D' to move or 'Q' to quit: ").upper()
if move == 'Q':
print("Quitting the game.")
break
if move == 'W':
new_board = move_up(board)
elif move == 'S':
new_board = move_down(board)
elif move == 'A':
new_board = move_left(board)
elif move == 'D':
new_board = move_right(board)
else:
continue
if board != new_board:
board = new_board
add_random(board)
if __name__ == "__main__":
main()
开始
|
V
初始化游戏板
|
V
主游戏循环
|
V
打印游戏板
|
V
检查是否胜利
|----> 是 ---> 打印胜利消息 --> 结束
|
V
检查是否可以移动
|----> 否 ---> 打印游戏结束消息 --> 结束
|
V
读取用户输入
|----> 'Q' --> 打印退出消息 --> 结束
|----> 'W' --> 移动上 --> 更新游戏板
|----> 'S' --> 移动下 --> 更新游戏板
|----> 'A' --> 移动左 --> 更新游戏板
|----> 'D' --> 移动右 --> 更新游戏板
|
V
添加随机数字
|
V
返回到主游戏循环