🎮 Мини-игра на Pygame: «Падающие блоки»
📌 Игрок управляет прямоугольником внизу экрана, уворачиваясь от падающих блоков. Каждый пропущенный блок даёт +1 очко.
🛠
Подпишись 👉🏻 @KodduuPython 🤖
import pygame, random, sys
pygame.init()
W, H = 400, 600
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
player = pygame.Rect(W//2-25, H-50, 50, 30)
blocks, speed, score = [], 5, 0
font = pygame.font.SysFont(None, 36)
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit(); sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.left > 0: player.move_ip(-7, 0)
if keys[pygame.K_RIGHT] and player.right < W: player.move_ip(7, 0)
if random.randint(1, 20) == 1:
blocks.append(pygame.Rect(random.randint(0, W-30), -30, 30, 30))
screen.fill((30, 30, 30))
pygame.draw.rect(screen, (0, 200, 0), player)
for b in blocks[:]:
b.move_ip(0, speed)
pygame.draw.rect(screen, (200, 50, 50), b)
if b.colliderect(player):
pygame.quit(); sys.exit()
if b.top > H:
blocks.remove(b)
score += 1
txt = font.render(f"Score: {score}", True, (255, 255, 255))
screen.blit(txt, (10, 10))
pygame.display.flip()
clock.tick(60)
📌 Игрок управляет прямоугольником внизу экрана, уворачиваясь от падающих блоков. Каждый пропущенный блок даёт +1 очко.
🛠
pip install pygame
Подпишись 👉🏻 @KodduuPython 🤖
❤3
Вот рабочая минималистичная версия «3D-like шутера» 👇
🕹 Управление:
* стрелки ← / → — смещают игрока
* клики мышкой — стреляют
Подпишись 👉🏻 @KodduuPython 🤖
import pygame, random, sys, math
pygame.init()
W, H = 640, 480
sc = pygame.display.set_mode((W, H))
clk = pygame.time.Clock()
player_x = 0
bullets = [] # [(x, z)]
enemies = [] # [(x, z)]
SPAWN = 30
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit(); sys.exit()
if e.type == pygame.MOUSEBUTTONDOWN:
mx, _ = pygame.mouse.get_pos()
bullets.append(((mx - W//2) / (W//2), 1.2))
keys = pygame.key.get_pressed()
player_x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 0.02
if random.randint(1, SPAWN) == 1:
enemies.append([random.uniform(-1, 1), 1.5])
sc.fill((10, 10, 30))
# обновляем врагов
new_enemies = []
for x, z in enemies:
z -= 0.01
if z <= 0.05: # достиг экрана
continue
scale = 1 / (z + 0.2)
sx = int(W//2 + x * scale * W//2)
sy = int(H - scale * H)
r = max(2, int(24 * scale))
pygame.draw.circle(sc, (200, 50, 50), (sx, sy), r)
new_enemies.append([x, z])
enemies = new_enemies
# обновляем пули
new_bullets = []
for x, z in bullets:
z -= 0.06
if z <= 0: # улетела
continue
scale = 1 / (z + 0.2)
sx = int(W//2 + x * scale * W//2)
sy = int(H - scale * H)
pygame.draw.circle(sc, (255, 255, 0), (sx, sy), max(1, int(6 * scale)))
hit = False
for ex, ez in enemies:
escale = 1 / (ez + 0.2)
exs = int(W//2 + ex * escale * W//2)
eys = int(H - escale * H)
if math.hypot(sx - exs, sy - eys) < (6*scale + 12*escale):
enemies.remove([ex, ez])
hit = True
break
if not hit:
new_bullets.append([x, z])
bullets = new_bullets
# рисуем игрока (пушка)
px = int(W//2 + player_x * W//2)
pygame.draw.polygon(sc, (100, 200, 250), [(px, H-10), (px-10, H-30), (px+10, H-30)])
pygame.display.flip()
clk.tick(60)
🕹 Управление:
* стрелки ← / → — смещают игрока
* клики мышкой — стреляют
Подпишись 👉🏻 @KodduuPython 🤖
❤4👍1
Минималистичный Raycasting движок в стиле Wolfenstein 3D (без оружия, просто ходьба по лабиринту). Это самый базовый, но реально рабочий 3D-эффект в
📌 Что умеет:
* простой raycasting-рендеринг
* лабиринт-карта задана как сетка (`game_map`)
* управление:
*
*
🛠
Подпишись 👉🏻 @KodduuPython 🤖
pygame.
import pygame, math, sys
pygame.init()
W, H = 640, 480
HALF_H = H // 2
TILE = 64
FOV = math.pi / 3
NUM_RAYS = 120
MAX_DEPTH = 800
DELTA_ANGLE = FOV / NUM_RAYS
DIST = NUM_RAYS / (2 * math.tan(FOV/2))
PROJ_COEFF = 3 * DIST * TILE
SCALE = W // NUM_RAYS
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
# карта: 1 = стена
game_map = {
(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),
(1,2),(1,3),(1,4),(1,5),(1,6),
(7,2),(7,3),(7,4),(7,5),(7,6),
(2,6),(3,6),(4,6),(5,6),(6,6)
}
px, py = W//4, H//4
angle = 0
def mapping(a,b): return (a//TILE)*TILE, (b//TILE)*TILE
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT: pygame.quit(); sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]: angle -= 0.04
if keys[pygame.K_RIGHT]: angle += 0.04
dx, dy = math.cos(angle)*2, math.sin(angle)*2
if keys[pygame.K_w]: px += dx; py += dy
if keys[pygame.K_s]: px -= dx; py -= dy
screen.fill((30,30,30))
pygame.draw.rect(screen, (100,100,100), (0,0,W,HALF_H)) # потолок
pygame.draw.rect(screen, (50,50,50), (0,HALF_H,W,HALF_H)) # пол
cur_angle = angle - FOV/2
for ray in range(NUM_RAYS):
sin_a, cos_a = math.sin(cur_angle), math.cos(cur_angle)
for depth in range(MAX_DEPTH):
x, y = px + depth*cos_a, py + depth*sin_a
if (x//TILE, y//TILE) in game_map:
depth *= math.cos(angle - cur_angle) # удаление "fish-eye"
proj_height = PROJ_COEFF / (depth+0.0001)
c = 255 / (1 + depth*depth*0.0001)
color = (c, c//2, c//3)
pygame.draw.rect(screen, color,
(ray*SCALE, HALF_H - proj_height//2, SCALE, proj_height))
break
cur_angle += DELTA_ANGLE
pygame.display.flip()
clock.tick(60)
📌 Что умеет:
* простой raycasting-рендеринг
* лабиринт-карта задана как сетка (`game_map`)
* управление:
*
← / → — поворот*
W / S — движение вперёд/назад🛠
pip install pygame
Подпишись 👉🏻 @KodduuPython 🤖
❤2
🚀 Минималистичный 3D-движок с каркасным рендерингом (Wireframe)
📌 Что делает:
* рендерит 3D-куб по принципу wireframe (каркас)
* есть вращение по всем осям
* 3D → 2D проекция через простую перспективу
🛠
Подпишись 👉🏻 @KodduuPython 🤖
import pygame, sys, math
pygame.init()
W, H = 800, 600
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
# Куб в 3D
vertices = [
[-1, -1, -1], [1, -1, -1],
[1, 1, -1], [-1, 1, -1],
[-1, -1, 1], [1, -1, 1],
[1, 1, 1], [-1, 1, 1]
]
edges = [
(0,1),(1,2),(2,3),(3,0),
(4,5),(5,6),(6,7),(7,4),
(0,4),(1,5),(2,6),(3,7)
]
def project(x, y, z, angle_x, angle_y, angle_z):
# вращение
cx, sx = math.cos(angle_x), math.sin(angle_x)
cy, sy = math.cos(angle_y), math.sin(angle_y)
cz, sz = math.cos(angle_z), math.sin(angle_z)
# поворот по X
y, z = y*cx - z*sx, y*sx + z*cx
# по Y
x, z = x*cy + z*sy, -x*sy + z*cy
# по Z
x, y = x*cz - y*sz, x*sz + y*cz
# проекция в 2D
fov, dist = 400, 5
factor = fov / (z + dist)
px, py = x * factor + W//2, -y * factor + H//2
return int(px), int(py)
angle_x = angle_y = angle_z = 0
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit(); sys.exit()
screen.fill((10, 10, 30))
angle_x += 0.02
angle_y += 0.03
angle_z += 0.01
# проекция вершин
projected = [project(x,y,z, angle_x, angle_y, angle_z) for x,y,z in vertices]
# рендер рёбер
for a,b in edges:
pygame.draw.line(screen, (0,200,255), projected[a], projected[b], 2)
pygame.display.flip()
clock.tick(60)
📌 Что делает:
* рендерит 3D-куб по принципу wireframe (каркас)
* есть вращение по всем осям
* 3D → 2D проекция через простую перспективу
🛠
pip install pygame
Подпишись 👉🏻 @KodduuPython 🤖
👍1
🎮 Самая минималистичная полная версия игры с бесконечным кол-вом уровней 🚀
📌 Описание:
* Игрок собирает ключи и открывает дверь для перехода на следующий уровень.
* Враги умные и идут к игроку, но не появляются рядом с ним.
* Стены блокируют движение игроков и врагов.
* Каждый уровень рандомный, с +1 врагом и +1 ключом на новом уровне.
🛠
Подпишись 👉🏻 @KodduuPython 🤖
import pygame,sys,random,math
pygame.init()
W,H=640,480
sc=pygame.display.set_mode((W,H))
clk=pygame.time.Clock()
font=pygame.font.SysFont(None,36)
level = 1
MIN_DIST = 150
def new_level(level):
player = pygame.Rect(50,50,30,30)
walls=[]
for _ in range(10):
w=pygame.Rect(random.randint(0,W-100),random.randint(0,H-100),
random.randint(50,150),random.randint(20,50))
if w.colliderect(player): continue
walls.append(w)
door = pygame.Rect(W-60,H-80,40,60)
keys = []
for _ in range(level):
while True:
k = pygame.Rect(random.randint(0,W-20),random.randint(0,H-20),20,20)
if any(k.colliderect(w) for w in walls) or k.colliderect(player) or k.colliderect(door): continue
keys.append(k); break
enemies=[]
for _ in range(level+1):
while True:
e = pygame.Rect(random.randint(0,W-30),random.randint(0,H-30),30,30)
if any(e.colliderect(w) for w in walls) or e.colliderect(player) or e.colliderect(door) or any(e.colliderect(k) for k in keys): continue
if math.hypot(e.x - player.x, e.y - player.y) < MIN_DIST: continue
enemies.append(e); break
return player, walls, door, keys, enemies
player, walls, door, keys, enemies = new_level(level)
got_keys = 0; game_over=False
def move_rect(rect, dx, dy):
rect.x += dx
if any(rect.colliderect(w) for w in walls): rect.x -= dx
rect.y += dy
if any(rect.colliderect(w) for w in walls): rect.y -= dy
def draw():
sc.fill((20,20,30))
pygame.draw.rect(sc,(0,200,0),player)
for e in enemies: pygame.draw.rect(sc,(200,50,50),e)
for w in walls: pygame.draw.rect(sc,(100,100,100),w)
for k in keys: pygame.draw.rect(sc,(255,255,0),k)
pygame.draw.rect(sc,(150,75,0),door)
sc.blit(font.render(f"Level: {level} Keys: {got_keys}/{len(keys)}",1,(255,255,255)),(10,10))
if game_over: sc.blit(font.render("Game Over",1,(255,0,0)),(W//2-80,H//2))
pygame.display.flip()
while True:
for ev in pygame.event.get():
if ev.type==pygame.QUIT: pygame.quit();sys.exit()
if not game_over:
keys_pressed=pygame.key.get_pressed()
dx=(keys_pressed[pygame.K_RIGHT]-keys_pressed[pygame.K_LEFT])*4
dy=(keys_pressed[pygame.K_DOWN]-keys_pressed[pygame.K_UP])*4
move_rect(player, dx, dy)
for e in enemies:
ex,ey = 0,0
if e.x < player.x: ex=2
elif e.x > player.x: ex=-2
if e.y < player.y: ey=2
elif e.y > player.y: ey=-2
move_rect(e, ex, ey)
if e.colliderect(player): game_over=True
for k in keys[:]:
if player.colliderect(k):
keys.remove(k); got_keys+=1
if player.colliderect(door) and got_keys==level:
level+=1
player, walls, door, keys, enemies = new_level(level)
got_keys=0
draw()
clk.tick(30)
📌 Описание:
* Игрок собирает ключи и открывает дверь для перехода на следующий уровень.
* Враги умные и идут к игроку, но не появляются рядом с ним.
* Стены блокируют движение игроков и врагов.
* Каждый уровень рандомный, с +1 врагом и +1 ключом на новом уровне.
🛠
pip install pygame
Подпишись 👉🏻 @KodduuPython 🤖
👍3
Процедурная генерация подземелья (roguelike-style) с помощью клеточного автомата.
👉 Что это делает:
* Генерирует карты-пещеры в стиле roguelike / Terraria.
* Используется клеточный автомат: случайная заготовка → несколько итераций «эволюции» → получается пещера.
Подпишись 👉🏻 @KodduuPython 🤖
import random, pygame
pygame.init()
W,H=800,600
T=10
C=(0,0,0)
Wc,Hc=W//T,H//T
s=pygame.display.set_mode((W,H))
def gen():
m=[[1 if random.random()<0.45 else 0 for x in range(Wc)] for y in range(Hc)]
for _ in range(5):
nm=[[0]*Wc for _ in range(Hc)]
for y in range(Hc):
for x in range(Wc):
cnt=sum(m[yy][xx] for yy in range(y-1,y+2) for xx in range(x-1,x+2) if 0<=xx<Wc and 0<=yy<Hc)
nm[y][x]=1 if cnt>=5 else 0
m=nm
return m
m=gen()
while True:
for e in pygame.event.get():
if e.type==pygame.QUIT:pygame.quit();exit()
for y in range(Hc):
for x in range(Wc):
pygame.draw.rect(s,(200,200,200) if m[y][x]==0 else C,(x*T,y*T,T,T))
pygame.display.flip()
👉 Что это делает:
* Генерирует карты-пещеры в стиле roguelike / Terraria.
* Используется клеточный автомат: случайная заготовка → несколько итераций «эволюции» → получается пещера.
Подпишись 👉🏻 @KodduuPython 🤖
Forwarded from AIGENTTO
Отвечаю на вопрос по извлечению фактов из чатов и текстов
Всё намного банальнее в реальности. Вот тут реальный кейс компании: ~10 000 сообщений, ~700 участников, 28 реальных вопросов-ответов, 25 реально недублирующихся устойчивых фактов. Всё остальное — шум типа «привет, пока, а как, а че, я тут подумал»...
LLM это выделяет очень хорошо. Конечно, важен промт.
Мы сейчас тестируем новый подход, в том числе к индексированию документов (Factology) — выделение фактов вместо простого чанкования. Как выяснилось, в документах тоже очень много воды и дубликатов.
И если в переписке был упомянут промт как промт, то в нашем случае LLM его сохранит как факт.
Главное — не переоценивать плотность информации в переписках и даже документах: там очень-очень-очень много воды. Нам людям так удобнее общаться, но для LLM это лишний шум.
А если надо извлечь эмоции из чатов, то это тоже можно сделать и отдельно сохранить, не держа весь объём переписок.
Подпишись 👉🏻 @aigentto 🤖
Всё намного банальнее в реальности. Вот тут реальный кейс компании: ~10 000 сообщений, ~700 участников, 28 реальных вопросов-ответов, 25 реально недублирующихся устойчивых фактов. Всё остальное — шум типа «привет, пока, а как, а че, я тут подумал»...
LLM это выделяет очень хорошо. Конечно, важен промт.
Мы сейчас тестируем новый подход, в том числе к индексированию документов (Factology) — выделение фактов вместо простого чанкования. Как выяснилось, в документах тоже очень много воды и дубликатов.
И если в переписке был упомянут промт как промт, то в нашем случае LLM его сохранит как факт.
Главное — не переоценивать плотность информации в переписках и даже документах: там очень-очень-очень много воды. Нам людям так удобнее общаться, но для LLM это лишний шум.
А если надо извлечь эмоции из чатов, то это тоже можно сделать и отдельно сохранить, не держа весь объём переписок.
Подпишись 👉🏻 @aigentto 🤖
Telegram
AIGENTTO
Плотность полезной информации в чатах
Дополнительным источником информации для базы знаний бота по компании могут быть переписки сотрудников в чатах. Если переписок много и они качественные (вопросы и ответы по теме), то это может стать и начальной базой…
Дополнительным источником информации для базы знаний бота по компании могут быть переписки сотрудников в чатах. Если переписок много и они качественные (вопросы и ответы по теме), то это может стать и начальной базой…
Добавим игрока, управление стрелками, и фонарик — освещается только область вокруг героя.
📌 Теперь:
* Карта генерируется процедурно.
* Игрок ходит стрелками, но не может пройти сквозь стены.
* Видна только область вокруг героя (фонарик).
Подпишись 👉🏻 @KodduuPython 🤖
import random,pygame,math
pygame.init()
W,H=800,600
T=10
C=(0,0,0)
Wc,Hc=W//T,H//T
s=pygame.display.set_mode((W,H))
clock=pygame.time.Clock()
def gen():
m=[[1 if random.random()<0.45 else 0 for x in range(Wc)] for y in range(Hc)]
for _ in range(5):
nm=[[0]*Wc for _ in range(Hc)]
for y in range(Hc):
for x in range(Wc):
cnt=sum(m[yy][xx] for yy in range(y-1,y+2) for xx in range(x-1,x+2)
if 0<=xx<Wc and 0<=yy<Hc)
nm[y][x]=1 if cnt>=5 else 0
m=nm
return m
m=gen()
px,py=W//2//T,H//2//T
r=80 # радиус фонаря в пикселях
while True:
for e in pygame.event.get():
if e.type==pygame.QUIT:pygame.quit();exit()
k=pygame.key.get_pressed()
dx,dy=0,0
if k[pygame.K_LEFT]:dx=-1
if k[pygame.K_RIGHT]:dx=1
if k[pygame.K_UP]:dy=-1
if k[pygame.K_DOWN]:dy=1
if 0<=px+dx<Wc and 0<=py+dy<Hc and m[py+dy][px+dx]==0:
px+=dx;py+=dy
# рисуем карту
s.fill(C)
for y in range(Hc):
for x in range(Wc):
if m[y][x]==0:
pygame.draw.rect(s,(200,200,200),(x*T,y*T,T,T))
# затемняем всё кроме круга фонаря
mask=pygame.Surface((W,H))
mask.fill((0,0,0))
mask.set_alpha(220)
pygame.draw.circle(mask,(0,0,0,0),(px*T+T//2,py*T+T//2),r)
s.blit(mask,(0,0))
pygame.draw.circle(s,(255,255,0),(px*T+T//2,py*T+T//2),4) # игрок
pygame.display.flip()
clock.tick(30)
📌 Теперь:
* Карта генерируется процедурно.
* Игрок ходит стрелками, но не может пройти сквозь стены.
* Видна только область вокруг героя (фонарик).
Подпишись 👉🏻 @KodduuPython 🤖
👍2
Добавим монстров в тёмных коридорах. Они будут случайно бродить, и если окажутся рядом — игра заканчивается.
📌 Теперь:
* В подземелье есть монстры с красными глазами 👀
* Они двигаются случайно по проходам.
* Если кто-то дошёл до тебя → Game Over.
* С ними реально страшнее, т.к. они прячутся в темноте.
Подпишись 👉🏻 @KodduuPython 🤖
import random,pygame,math
pygame.init()
W,H=800,600
T=10
C=(0,0,0)
Wc,Hc=W//T,H//T
s=pygame.display.set_mode((W,H))
clock=pygame.time.Clock()
def gen():
m=[[1 if random.random()<0.45 else 0 for x in range(Wc)] for y in range(Hc)]
for _ in range(5):
nm=[[0]*Wc for _ in range(Hc)]
for y in range(Hc):
for x in range(Wc):
cnt=sum(m[yy][xx] for yy in range(y-1,y+2) for xx in range(x-1,x+2)
if 0<=xx<Wc and 0<=yy<Hc)
nm[y][x]=1 if cnt>=5 else 0
m=nm
return m
m=gen()
px,py=W//2//T,H//2//T
r=80 # радиус фонаря
monsters=[(random.randint(1,Wc-2),random.randint(1,Hc-2)) for _ in range(5)]
while any(m[y][x]==1 or (x,y)==(px,py) for x,y in monsters):
monsters=[(random.randint(1,Wc-2),random.randint(1,Hc-2)) for _ in range(5)]
while True:
for e in pygame.event.get():
if e.type==pygame.QUIT:pygame.quit();exit()
k=pygame.key.get_pressed()
dx,dy=0,0
if k[pygame.K_LEFT]:dx=-1
if k[pygame.K_RIGHT]:dx=1
if k[pygame.K_UP]:dy=-1
if k[pygame.K_DOWN]:dy=1
if 0<=px+dx<Wc and 0<=py+dy<Hc and m[py+dy][px+dx]==0:
px+=dx;py+=dy
# движение монстров случайно
new_monsters=[]
for x,y in monsters:
if random.random()<0.3:
mx,my=random.choice([(1,0),(-1,0),(0,1),(0,-1)])
if 0<=x+mx<Wc and 0<=y+my<Hc and m[y+my][x+mx]==0:
x,y=x+mx,y+my
new_monsters.append((x,y))
monsters=new_monsters
# проверка столкновения
for x,y in monsters:
if abs(px-x)<=0 and abs(py-y)<=0:
print("Game Over! Monster caught you!")
pygame.quit();exit()
# рисуем карту
s.fill(C)
for y in range(Hc):
for x in range(Wc):
if m[y][x]==0:
pygame.draw.rect(s,(200,200,200),(x*T,y*T,T,T))
# монстры (красные глаза)
for x,y in monsters:
pygame.draw.circle(s,(255,0,0),(x*T+T//2,y*T+T//2),3)
# затемняем всё кроме круга фонаря
mask=pygame.Surface((W,H))
mask.fill((0,0,0))
mask.set_alpha(220)
pygame.draw.circle(mask,(0,0,0,0),(px*T+T//2,py*T+T//2),r)
s.blit(mask,(0,0))
pygame.draw.circle(s,(255,255,0),(px*T+T//2,py*T+T//2),4) # игрок
pygame.display.flip()
clock.tick(10)
📌 Теперь:
* В подземелье есть монстры с красными глазами 👀
* Они двигаются случайно по проходам.
* Если кто-то дошёл до тебя → Game Over.
* С ними реально страшнее, т.к. они прячутся в темноте.
Подпишись 👉🏻 @KodduuPython 🤖
👍2
И бесконечная карта с монстрами 👻
Подпишись 👉🏻 @KodduuPython 🤖
import random,pygame
pygame.init()
W,H=800,600;T=10
Wc,Hc=W//T,H//T
s=pygame.display.set_mode((W,H))
clock=pygame.time.Clock()
CH,CW=60,80;C=(0,0,0)
def gen_chunk(cx,cy):
m=[[1 if random.random()<0.45 else 0 for x in range(CW)] for y in range(CH)]
for _ in range(5):
nm=[[0]*CW for _ in range(CH)]
for y in range(CH):
for x in range(CW):
cnt=sum(m[yy][xx] for yy in range(y-1,y+2) for xx in range(x-1,x+2)
if 0<=xx<CW and 0<=yy<CH)
nm[y][x]=1 if cnt>=5 else 0
m=nm
mons=[]
for _ in range(random.randint(1,4)):
while True:
x,y=random.randrange(CW),random.randrange(CH)
if m[y][x]==0:
mons.append((cx*CW+x,cy*CH+y));break
return m,mons
chunks={};monsters=[]
def get_tile(gx,gy):
cx,cy=gx//CW,gy//CH
lx,ly=gx%CW,gy%CH
if (cx,cy) not in chunks:
m,mons=gen_chunk(cx,cy)
chunks[(cx,cy)]=m
monsters.extend(mons)
return chunks[(cx,cy)][ly][lx]
px,py=0,0;r=80
tick=0
def move_monster(x,y):
if abs(px-x)<8 and abs(py-y)<8:
dx=1 if px>x else -1 if px<x else 0
dy=1 if py>y else -1 if py<y else 0
if get_tile(x+dx,y+dy)==0:return x+dx,y+dy
return (x,y)
while True:
for e in pygame.event.get():
if e.type==pygame.QUIT:pygame.quit();exit()
k=pygame.key.get_pressed();dx=dy=0
if k[pygame.K_LEFT]:dx=-1
if k[pygame.K_RIGHT]:dx=1
if k[pygame.K_UP]:dy=-1
if k[pygame.K_DOWN]:dy=1
if get_tile(px+dx,py+dy)==0:px+=dx;py+=dy
tick+=1
if tick%2==0: # монстры двигаются медленнее
monsters=[move_monster(x,y) for x,y in monsters]
if any(mx==px and my==py for mx,my in monsters): # проверка смерти
print("GAME OVER!")
pygame.quit();exit()
camx,camy=px-Wc//2,py-Hc//2
s.fill(C)
for y in range(Hc):
for x in range(Wc):
gx,gy=camx+x,camy+y
if get_tile(gx,gy)==0:
pygame.draw.rect(s,(200,200,200),(x*T,y*T,T,T))
for mx,my in monsters:
if camx<=mx<camx+Wc and camy<=my<camy+Hc:
pygame.draw.circle(s,(255,0,0),((mx-camx)*T+T//2,(my-camy)*T+T//2),3)
mask=pygame.Surface((W,H));mask.fill((0,0,0));mask.set_alpha(220)
pygame.draw.circle(mask,(0,0,0,0),(W//2,H//2),r)
s.blit(mask,(0,0))
pygame.draw.circle(s,(255,255,0),(W//2,H//2),4)
pygame.display.flip();clock.tick(10)
Подпишись 👉🏻 @KodduuPython 🤖
Мини версия игры Boxing 👊
Подпишись 👉🏻 @KodduuPython 🤖
import pygame,sys,random,math
pygame.init()
W,H=640,480
s=pygame.display.set_mode((W,H))
c=pygame.time.Clock()
f=pygame.font.SysFont(None,24)
ph,eh=100,100
cdp,atk=0,0
pf=[{'r':60,'x':W//2-120,'y':H-80,'st':0},{'r':60,'x':W//2+120,'y':H-80,'st':0}]
ef=[{'r':40,'x':W//2-60,'y':H//2+120,'st':0},{'r':40,'x':W//2+60,'y':H//2+120,'st':0}]
fx,fy,ft,t=0,0,0,0
fsx,fsy,shx,shy=0,0,0,0
pl,pr={'x':0,'y':0},{'x':0,'y':0}
scs,pscs=[],[]
def dr():
ox,oy=shx,shy
s.fill((0,0,0))
pygame.draw.rect(s,(255,0,0),(50+ox,30+oy,ph*2,20))
pygame.draw.rect(s,(0,255,0),(W-250+ox,30+oy,eh*2,20))
cx,cy=W//2+fx+fsx+ox,H//2+fy+fsy+oy
pygame.draw.circle(s,(255,220,200),(cx,cy),120)
for sx,sy,l,a in scs:
ex,ey=cx+sx+math.cos(a)*l,cy+sy+math.sin(a)*l
pygame.draw.line(s,(150,0,0),(cx+sx,cy+sy),(ex,ey),2)
exs,eys=fx//5,fy//5
el,er=(cx-40+exs,cy-40+eys),(cx+40+exs,cy-40+eys)
pygame.draw.circle(s,(0,0,0),el,20);pygame.draw.circle(s,(0,0,0),er,20)
pygame.draw.circle(s,(255,255,255),(int(el[0]+pl['x']),int(el[1]+pl['y'])),5)
pygame.draw.circle(s,(255,255,255),(int(er[0]+pr['x']),int(er[1]+pr['y'])),5)
pygame.draw.rect(s,(0,0,0),(cx-50+exs,cy+40+eys,100,20))
for q in ef:pygame.draw.circle(s,(200,50,50),(q['x']+ox,q['y']+oy),q['r'])
for q in pf:pygame.draw.circle(s,(200,200,200),(q['x']+ox,q['y']+oy),q['r'])
for sx,sy,l,a in pscs:
ex,ey=sx+math.cos(a)*l,sy+math.sin(a)*l
pygame.draw.line(s,(255,50,50),(sx,sy),(ex,ey),3)
s.blit(f.render(f"P:{ph} E:{eh}",1,(255,255,255)),(W//2-40+ox,5+oy))
pygame.display.flip()
def punch():
global fsx,fsy,scs
q=random.choice(pf);q.update({'r':90,'x':W//2+random.randint(-40,40),'y':H//2+random.randint(-40,40),'st':1})
fsx,fsy=random.randint(-q['r'],q['r']),random.randint(-q['r']//2,q['r']//2)
scs.append((random.randint(-100,100),random.randint(-100,100),random.randint(10,40),random.uniform(0,6.28)))
def eatk():
global ph,shx,shy,pscs
q=random.choice(ef);q.update({'r':120,'y':H//2+30,'st':1})
ph=max(0,ph-q['r']//10)
shx,shy=random.randint(-q['r']//2,q['r']//2),random.randint(-q['r']//2,q['r']//2)
for _ in range(random.randint(1,3)):
sx,sy,l,ang=random.randint(0,W),random.randint(0,H),random.randint(80,200),random.uniform(-.5,.5)
pscs.append((sx,sy,l,ang))
while 1:
for e in pygame.event.get():
if e.type==pygame.QUIT:pygame.quit();sys.exit()
if e.type==pygame.KEYDOWN and e.key==pygame.K_SPACE and cdp==0:punch();cdp=20
if cdp>0:cdp-=1
if t==0:ft={'x':random.choice([-30,0,30]),'y':random.choice([-20,0,10])};t=random.randint(20,40)
else:fx+=(ft['x']-fx)//10;fy+=(ft['y']-fy)//10;t-=1
fsx//=2;fsy//=2;shx//=2;shy//=2
pl['x']+=(-fx//5-pl['x'])//5;pl['y']+=(-fy//5-pl['y'])//5
pr['x']+=(-fx//5-pr['x'])//5;pr['y']+=(-fy//5-pr['y'])//5
for i,q in enumerate(pf):
if q['st']:q['r']-=5;q['y']+=4
else:
ix=W//2-120 if i==0 else W//2+120
if q['r']<60:q['r']+=2
if q['y']<H-80:q['y']+=2
q['x']+=(ix-q['x'])//5
if q['st'] and q['r']<=30:
eh=max(0,eh-max(5,25-q['r']));q['st']=0
for i,q in enumerate(ef):
if q['st']:q['r']-=3;q['y']+=2
else:
ix=W//2-60 if i==0 else W//2+60
if q['r']<40:q['r']+=2
if q['y']<H//2+120:q['y']+=2
q['x']+=(ix-q['x'])//5
if q['st'] and q['r']<=40:q['st']=0
atk+=1
if atk>60:eatk();atk=0
dr()
if ph<=0 or eh<=0:
m="Win!"if eh<=0 else"Lose!"
s.fill((0,0,0));s.blit(f.render(m,1,(255,255,255)),(W//2-20,H//2));pygame.display.flip();pygame.time.wait(2000)
ph,eh=100,100;pf=[{'r':60,'x':W//2-120,'y':H-80,'st':0},{'r':60,'x':W//2+120,'y':H-80,'st':0}]
ef=[{'r':40,'x':W//2-60,'y':H//2+120,'st':0},{'r':40,'x':W//2+60,'y':H//2+120,'st':0}]
fx,fy,ft,t,fsx,fsy,shx,shy,pl,pr,scs,pscs,atk=0,0,{'x':0,'y':0},0,0,0,0,0,{'x':0,'y':0},{'x':0,'y':0},[],[],0
c.tick(30)
Подпишись 👉🏻 @KodduuPython 🤖
В Python 3.14 теперь можно ветвить логику прямо по типам (type-based branching),
а не только по значениям.
Это стало возможным благодаря `match` + `type` pattern matching и новым возможностям
### ⚙️ Пример: ветвление по типу аргумента
📌 Как это работает:
*
что если условие
* Таким образом, мы получаем ветвление логики по типу
без ручных
* Python 3.14 поддерживает это *официально* в стандартном
🛠 всё работает "из коробки" на Python 3.14+
Подпишись 👉🏻 @KodduuPython 🤖
а не только по значениям.
Это стало возможным благодаря `match` + `type` pattern matching и новым возможностям
typing — например, TypeIs и TypeGuard.### ⚙️ Пример: ветвление по типу аргумента
from typing import TypeGuard
def is_str(x: object) -> TypeGuard[str]:
return isinstance(x, str)
def process(x: int | str):
if is_str(x):
# здесь x уже гарантированно str
print(f"Строка: {x.upper()}")
else:
# а здесь — int
print(f"Число: {x * 2}")
process("hi")
process(10)
📌 Как это работает:
*
TypeGuard сообщает анализатору типов (mypy, Pyright, IDE),что если условие
is_str(x) истинно — то дальше x считается str.* Таким образом, мы получаем ветвление логики по типу
без ручных
isinstance() проверок везде.* Python 3.14 поддерживает это *официально* в стандартном
typing.🛠 всё работает "из коробки" на Python 3.14+
Подпишись 👉🏻 @KodduuPython 🤖
🔥 Python 3.14: Free-threading и реальное многопоточность без GIL
📌 Что важно:
* В Python 3.14 есть официальная поддержка free-threaded build (CPython без GIL) ([Python documentation][1])
* Если собрать интерпретатор с параметром
* В этом режиме CPU-bound задачи через потоки реально параллелятся, что даёт значительное ускорение на многопроцессорных машинах ([InfoWorld][2])
🛠 Необходимо: собрать/установить free-threaded CPython (с
Подпишись 👉🏻 @KodduuPython 🤖
import sys, threading, time
def worker(n):
s = 0
for i in range(n):
s += i*i
return s
def benchmark(n, threads):
ts = []
for _ in range(threads):
t = threading.Thread(target=worker, args=(n,))
ts.append(t)
t.start()
for t in ts:
t.join()
if __name__ == "__main__":
print("GIL enabled:", sys._is_gil_enabled())
start = time.time()
benchmark(10_000_000, 4)
end = time.time()
print("Time:", end-start)
📌 Что важно:
* В Python 3.14 есть официальная поддержка free-threaded build (CPython без GIL) ([Python documentation][1])
* Если собрать интерпретатор с параметром
--disable-gil, или установить free-threaded образ на Windows/macOS, sys._is_gil_enabled() покажет что GIL отключён ([Python documentation][1])* В этом режиме CPU-bound задачи через потоки реально параллелятся, что даёт значительное ускорение на многопроцессорных машинах ([InfoWorld][2])
🛠 Необходимо: собрать/установить free-threaded CPython (с
--disable-gil`) или использовать официальный билд, поддерживающий GIL офф :contentReference[oaicite:3]{index=3}`.Подпишись 👉🏻 @KodduuPython 🤖
❤2