Python 控制台交互练习
几个 Python 控制台交互练习
用 python 写了个3D旋转三角形
先上效果图!
然后是代码!
import random
# import numpy as np #
import math
import os
import time
os.system("title welcome to 3D try of snowstar.")
# 今天来做一个 显示 #D 图形的实验
# 好的开始!
# 首先,构造一个三维空间
# ↑ 没错,构造完了
# 给刚才构造的物体连一连线,这样会比较直观一点!
def makePointsFromLine(pointA, pointB):
t = 0
step = 1
points = []
# 嗯,教科书式的求两点距离公式
pointDistance = math.sqrt(
(pointB[0] - pointA[0]) ** 2 +
(pointB[1] - pointA[1]) ** 2 +
(pointB[2] - pointA[2]) ** 2 )
# 百分比步伐。。。这里x0.9的意思是步子小一点点,让点稍微密一点点(当然也会更慢)
percentStep = (1.0 / pointDistance) * 0.9
# 基本上就是把这条线切成好多个点,每个点的距离是这条线的 百分之 percent
percent = 0
while percent <= 1:
x = int(round(pointA[0] + percent * (pointB[0] - pointA[0])))
y = int(round(pointA[1] + percent * (pointB[1] - pointA[1])))
z = int(round(pointA[2] + percent * (pointB[2] - pointA[2])))
points.append([x, y, z])
percent += percentStep
return points
# 我发誓这是我取过的最长的函数名了。。。2016年8月29日17:41:08
def makePointsFromLinesFromPointsToPoints(dongXi):
pointsFromLines = []
len = dongXi.__len__()
for a in range(len):
for b in range(a + 1, len):
pointA = dongXi[a]
pointB = dongXi[b]
pointsFromLines += makePointsFromLine(pointA, pointB)
return pointsFromLines
# 嗯好了,来画一个屏幕
w = 59
h = 26
# 这个就是被拍扁的z轴了(看不懂跳过,先看下面
zlist = []
# 用不同的符号表示远近,越粗的越近,模拟近大远小
zsign = ["@@", "88", "OO", ";;","::", "..", " ."]
zsignlen = zsign.__len__()
# 这个函数决定屏幕上的某点显示什么鬼,是整个程序中最核心的部分
def posChar(x, y):
global zlist
global zlistlen
global zsign
global zsignlen
global points
global points2D
i = 0
if [x, y] not in points2D: # 去掉那些没有点的地方
return " "
for z in zlist: # 按z轴 从大到小询问,这里有没有人啊!!有没有啊!!
if [x, y, z] in points: # 如果有的话!!就印出来啦!!
return zsign[ int(i * zsignlen / zlistlen) ]
i += 1 # 嗯, i变大的时候,zsign 的图画就会变小了
return "XX" # 理论上这条不会被运行到,不过。。。万一我蠢呢!!!
# 这个函数是去除重复的点用的
def removeDupes(seq):
checked = []
for e in seq:
if e not in checked:
checked.append(e)
return checked
def perpareForPoints():
# 给上面的那个奇怪的形状,画成线,然后得到一堆点
global points
global zlist
global zlistlen
global points
global points2D
points = [[int(round(v)) for v in point] for point in pointSource]
# 画完之后是一堆3D空间上的点,把Z轴拍扁,变成2D空间点集
points2D = [point[0:2] for point in points]
# 接下来要抠掉多余的因为拍扁而 叠在一起的2D的点,每个位置留一个就够啦
points2D = removeDupes(points2D)
# 聪明的你已经发现。。上面2步只用1行就可以完成...
# 然后把那个3D的点集排成一个z轴,让它分一分前后
zlist = [point[2] for point in points]
zlist.sort(reverse=True) # 从大到小排,大的在前面
zlistlen = zlist.__len__()
def draw():
# 开始渲染!!
buf = []
buf.append("="*45+"welcome to 3D try of snowstar."+"="*44)
for y in range(-int(h/2), h-int(h/2)):
# 这么要紧的地方怎么可以没有注释呢!!!!嗯有了
buf.append("".join([ posChar(x, y) for x in range(-int(w/2), w-int(w/2))] ) + " ")
buf.append("="*45+"welcome to 3D try of snowstar."+"="*44)
# 打到屏幕上
os.system("cls")
print("\n".join(buf))
time.sleep( 1.0/61 ) # 设定为 60 fps
# 定义几个矩阵计算用的函数
# 别问我为什么不用numpy.....
# 因为。。。。我要用这东西教小盆友的啊!
# 这样我就不用再教人家装numpy啦!!!(好像更麻烦了呢
def 转置矩阵(矩阵):
len = 矩阵[0].__len__()
输出矩阵 = []
for i in range(len):
输出矩阵.append([行向量[i] for 行向量 in 矩阵])
return 输出矩阵
def 向量点积向量(向量A, 向量B):
if len(向量A) != len(向量B):
raise("雪星你又蠢啦两向量点积长度必须相同才行")
结果 = 0
for i in range(len(向量A)):
结果 += 向量A[i] * 向量B[i]
return 结果
def 向量点积矩阵(向量A, 矩阵B):
输出向量 = []
for 行向量 in 转置矩阵(矩阵B):
输出向量.append( 向量点积向量(向量A, 行向量) )
return 输出向量
def 矩阵点积矩阵(矩阵A, 矩阵B):
输出矩阵 = []
for 行向量 in 矩阵A:
输出矩阵.append( 向量点积矩阵(行向量, 矩阵B) )
return 输出矩阵
# 旋转函数
def rotating():
global wuti
global pointSource
theta = 0.05 # 不懂是多少度总之能转起来就行啦
# 这是一个普通的2D旋转矩阵,直接查 wiki 就可以啦
a, b = math.cos(theta), -math.sin(theta)
c, d = math.sin(theta), math.cos(theta)
# 把y轴方向固定下来,不让它转,让其它轴绕着它转
rotateMatrix = [[a, 0, b],
[0, 1, 0],
[c, 0, d]]
# 怎么转呢?直接点积啦
wuti = 矩阵点积矩阵(wuti, rotateMatrix)
# 不够过瘾? 再加个X轴! 以 1/4 的几率旋转,那么它就会得到一个浮动的效果。。。
if random.random() <= 1/4 and (int(time.time()) % 60) < 20:
# 把x轴方向固定下来,不让它转,让其它轴绕着它转
rotateMatrix = [[1, 0, 0],
[0, a, b],
[0, c, d]]
# 怎么转呢?直接点积啦
wuti = 矩阵点积矩阵(wuti, rotateMatrix)
pointSource = makePointsFromLinesFromPointsToPoints(wuti)
# 接下来构造一个三维物体,比如说……
# 三棱锥! P-ABC !!
# 大概长这样
# *-------*
# \\ //
# \\ //
# \ * /
# \|/
# *
wuti = [
[-10, -10, -10], # 点A
[ 10, -10, -10], # 点B
[ 0, 10, -10], # 点C
[ 0, 0, 10], # 点P
]
# 来初始化一下,第一个图形!
pointSource = makePointsFromLinesFromPointsToPoints(wuti)
perpareForPoints()
# 运行啦!!!!
fps = 0
t = time.time()
while(True):
draw()
rotating()
perpareForPoints()
dt = time.time() - t
t += dt
os.system("title " + "fts: %d" % (1 / dt))
Python 控制台打印函数图像
Python 代码如下,运行环境windows
# 让控制台使用 UTF-8 编码
import os; os.system("chcp 65001 & cls")
import math
import random
def plot(f):
print("="*89)
print("现在打印的是", f, "的函数图象")
# 打印范围 x 为正负 20
w = int(40 / 2)
# 生成点集
arrPos = [[x, round(f(x))] for x in range(-w, w+1)]
# 生成y坐标集
rangelist = [x[1] for x in arrPos]
for y in range(max(rangelist), min(rangelist)-1,-1):
print("".join([(
([x, y] in arrPos and y == 0 and "-*") or
[x, y] in arrPos and " *" or
x == 0 and y == 0 and "-|" or
x == 0 and " |" or
y == 0 and "--" or
" "
) for x in range(-w,w)]))
plot(lambda x:
((15**2) - x ** 2 >= 0) and math.sqrt((15**2) - x ** 2) * random.choice([1,-1])
)
input()
Python 50 行代码写个贪吃蛇
50行python代码写个贪吃蛇
别问我为什么这么无聊,我只是想告诉一个小朋友。。。贪吃蛇真的不需要用150行来写 上图
import random
import msvcrt # 读取键盘要用
import os; os.system("chcp 65001 & cls") # 设定控制台编码为UTF8
w, h = 30, 15 # 沙盘大小设定
directions = {72:[0,-1],77:[1,0],80:[0,1],75:[-1,0]} # 四个方向,用方向键低位编号表示
headpos = [random.randint(0, w-1), random.randint(0, h-1)] # 头部位置
headdpos = directions[random.choice([72,77,80,75])] # 头部位置的变化,相当于头部方向
snake = [headpos] #蛇身,其实就是一堆坐标
foods = [] #食物
def posChar(pos): #决定某个坐标显示的东西
return ((pos in snake and "*") or
(pos in foods and "%") or " " )
def printSnake():
outputs = []
outputs.append("欢迎来到雪星实验室 - 贪吃蛇 ================================")
for y in range(h):
outputs.append("|" + " ".join([ posChar([x, y]) for x in range(w)] ) + " |")
outputs.append("欢迎来到雪星实验室 - 贪吃蛇 ================================")
os.system("cls")
print("\n".join(outputs))
def go():
global headdpos
global headpos
if random.random() < 0.1 or foods.__len__() == 0:
foods.append([random.randint(0, w-1), random.randint(0, h-1)])
printSnake() #先打印当前地图
userkey = msvcrt.getch() == b'\xe0' and msvcrt.getch() or " " # 等待用户按键
headdpos = directions.get(ord(userkey), headdpos) # 根据按键设定方向
headpos = [x+y for x, y in zip(headpos, headdpos)] # 坐标相加
snake.insert(0, headpos) # 向头部前进一个位置
if headpos in foods: # 如果吃到了食物
foods.remove(headpos) # 就移除这个食物
else: #如果没东西吃
snake.pop() # 那蛇尾就没掉了
def liveQ():
return ((headpos[0] in range(w) and headpos[1] in range(h)) # 没撞墙
and (not headpos in snake[2:] ) ) # 也没撞自己
while(liveQ()):
go()
print("大侠请重新来过 ..................")
input()
Snowstar Miao.