Trò chơi Frogger-ish


13

Làm thế nào về việc mang lại cho trò chơi arcade ol 'tốt Frogger hồi sinh, theo phong cách Code Golf!

Nhiệm vụ của bạn là tạo ra một phiên bản của trò chơi cổ điển này, với càng ít ký tự mã càng tốt. Sử dụng ngôn ngữ bạn chọn (thư viện, như jQuery , v.v., được cho phép).

Yêu cầu

  • Bạn có 3 mạng và mất 1 mạng từ:
    • di chuyển ra ngoài cảnh trò chơi.
    • bị tấn công bởi một sự kịch liệt
    • nhảy xuống nước
    • nhảy đến một ngôi nhà đã bị chiếm đóng
    • hết thời gian rồi.
  • Con ếch di chuyển bằng các phím mũi tên.
  • Có một lỗi "dịch chuyển tức thời" với các khoảng thời gian được đặt giữa năm ngôi nhà (khoảng trống giữa cỏ ở trên cùng).
  • Bạn nhận được 10 điểm khi di chuyển một bước về phía trước, 200 điểm thưởng khi bắt lỗi và 500 điểm khi đến một ngôi nhà trống.
  • Một bộ đếm thời gian tích tắc, nhanh hơn mọi cấp độ (các phương tiện, ếch và khúc gỗ nên di chuyển nhanh hơn theo từng cấp độ).
  • Cần có 5 làn xe và 3 làn có khúc gỗ và 2 làn với rùa.
  • Mỗi làn nên di chuyển theo tốc độ được chọn ngẫu nhiên (trong lý do).
  • Khi một ngôi nhà có sẵn bị chiếm đóng, một con ếch xuất hiện ở điểm bắt đầu và bạn điều khiển nó từ điểm đó.
  • Khi tất cả năm ngôi nhà đã bị chiếm đóng, bộ đếm thời gian khởi động lại và các ngôi nhà trở nên trống rỗng. Khi trò chơi kết thúc, điểm từ tất cả các cấp được tính toán và hiển thị.

thông tin bổ sung

Màn hình bắt đầu, âm nhạc và bảng điểm cao là không cần thiết. Bạn cũng không cần phải bắt chước thiết kế theo pixel. Bạn muốn nó màu đen và trắng? Bạn muốn nó thực sự tối giản? Hoặc một khối thay vì một con ếch hoặc xe hơi? Hoạt động tốt! Chỉ cần giữ mã chặt chẽ. Mã ngắn nhất sẽ thắng!

nhập mô tả hình ảnh ở đây


Bình luận bị thanh trừng vì chúng đã lỗi thời. Vui lòng thông báo cho tôi về bất kỳ thông tin bị mất có thể đã bị xóa trong các bình luận.
Doorknob

Câu trả lời:


3

Con trăn 3.3 - Bị đánh cắp

Tôi chưa bao giờ chơi golf này, vì tôi thích thú hơn khi chỉ cần làm cho một trò chơi đẹp mắt hoạt động trước tiên. Tôi thực sự hoàn toàn mới đối với Tk, vì vậy nếu có ai có bất kỳ đề xuất nào, tôi thực sự sẽ đánh giá cao họ. Tốc độ bây giờ hoạt động đúng. Hãy cho tôi biết nếu bạn muốn xem các tính năng bổ sung, ví dụ như màu sắc.

import tkinter as tk
import queue
import random    

class Lane():
 def __init__(self, row=-1, lanetype="none", direction=0, speed=0, width=0, maxnumber=0, replenish=0, length=0, gap=0):
  self.row = row
  self.type = lanetype
  self.direction = direction
  self.speed = speed
  self.width = width
  self.maxnumber = maxnumber
  self.replenish = replenish
  self.length = length
  self.gap = gap
  self.lanelastupdate = 0
  self.objects = []
  if(self.type == "car"):
   for index in range(self.width):
    if(len(self.objects) == self.maxnumber):
     break
    if((self.maxnumber - len(self.objects) == self.width - index) or random.random() < self.maxnumber/self.width):
     self.objects.append([index*self.direction + int((self.width-1)/2 - (self.width-1)*self.direction/2), self.row])
  if(self.type == "log" or self.type == "turtle"):
   if(self.direction == 1):
    start = 0
   else:
    start = self.width - 1
   lengthcounter = 0
   gapcounter = 0
   for index in range(self.width):
    if(lengthcounter < self.length):
     self.objects.append([start + index*self.direction, self.row])
     lengthcounter += 1
    else:
     gapcounter += 1
     if(gapcounter == self.gap):
      lengthcounter = 0
      gapcounter = 0
 ### end of __init__ ###
### end of Lane class ###

class Frogger():
 def __init__(self):
  # configure 'global' variables
  self.directions = ['Up', 'Down', 'Left', 'Right']
  self.width = 25
  self.height = 13
  self.frogstart = [12, 12]
  self.pointsforup = 10
  self.pointsforhome = 500
  self.pointsforbug = 200
  self.timerthreshold = 1000
  self.timerstart = 60
  self.speedchange = 2
  self.waterbordertop = 1
  self.waterborderbottom = 5
  self.minspeed = 10
  self.maxspeed = 15
  self.minbugspeed = 50
  self.maxbugspeed = 100
  self.timerspeed = 20    

  # configure program state variables
  self.q = queue.Queue(maxsize=1)
  self.updateticks = 0

  # configure game variables
  self.gameover = False
  self.speedup = 0
  self.timer = self.timerstart
  self.lives = 3
  self.score = 0
  self.frogposition = [0, 0]
  self.frogposition[0] = self.frogstart[0]
  self.frogposition[1] = self.frogstart[1]
  self.highest = 12
  self.movedup = False

  # configure the lanes of cars, logs, and turtles
  self.init_lanes()

  # configure the homes and the bug
  self.init_special()

  # configure TK window
  self.root = tk.Tk()
  self.label = tk.Label(text="Score: "+str(self.score)+" Lives: "+str(self.lives)+" Time: "+str(self.timer))
  self.label.pack()
  self.text = tk.Text(self.root, width=self.width, height=self.height, font=("Courier New", 14))
  self.text.bind("<Key>", self.key_event)
  self.text.focus_set()
  self.text.pack()

  # configure drawing sprites
  self.init_sprites()

  # run the game
  self.update_clock()
  self.process_world()
  self.root.mainloop()
 ### end of init ###

 def init_sprites(self):
  self.symbols = {"frog":chr(0x238), "rightcar":chr(187), "leftcar":chr(171), "turtle":chr(920), "log":chr(685), "bug":chr(1217), "grass":chr(993), "freehome":chr(164), "fullhome":"@", "road":"-", "water":chr(0x2248), "saferow":"*"}
  self.sprites = {value:key for key, value in self.symbols.items()}
  self.text.tag_configure("frog", foreground="chartreuse", background="dark green")
  self.text.tag_configure("rightcar", foreground="yellow", background="black")
  self.text.tag_configure("leftcar", foreground="yellow", background="black")
  self.text.tag_configure("turtle", foreground="orange red", background="cyan")
  self.text.tag_configure("log", foreground="sienna", background="cyan")
  self.text.tag_configure("bug", foreground="maroon", background="green")
  self.text.tag_configure("grass", foreground="orange", background="green")
  self.text.tag_configure("freehome", foreground="forest green", background="green")
  self.text.tag_configure("fullhome", foreground="red", background="green")
  self.text.tag_configure("road", foreground="gray", background="black")
  self.text.tag_configure("water", foreground="navy", background="cyan")
  self.text.tag_configure("saferow", foreground="pink", background="black")
 ### end of init_sprites ###

 def update_clock(self):
  self.timer -= 1
  self.label.configure(text="Score: "+str(self.score)+" Lives: "+str(self.lives)+" Time: "+str(self.timer))
  if(self.gameover == False):
   self.root.after(max(1, self.timerthreshold - self.speedup), self.update_clock)
 ### end of update_clock ###

 def key_event(self, event):
  direction = event.keysym
  if(direction in self.directions):
   try:
    self.q.put(direction, block=False)
   except:
    pass
 ### end of key_event ###

 def process_world(self):
  # acquire user input and process it if necessary
  if(self.q.qsize() > 0):
   self.move_frog(self.q.get())

  # update the state of non-frog objects
  self.update_world()

  # draw the world
  self.draw_world()

  # schedule another pass unless the game is over
  if(self.gameover == False):
   self.root.after(self.timerspeed, self.process_world)
  else:
   self.root.after(self.timerspeed, self.gameover_screen)
 ### end of process_world ###

 def move_frog(self, d):
  x = self.frogposition[0]
  y = self.frogposition[1]
  if(d == 'Up'):
   y -= 1
  elif(d == 'Down'):
   y += 1
  elif(d == 'Left'):
   x -= 1
  else:
   x += 1
  if(x >= 0 and y >= 0 and x < self.width and y < self.height):
   self.frogposition[0] = x
   self.frogposition[1] = y
   self.movedup = False
   if(d == 'Up' and y < self.highest):
    self.movedup = True
 ### end of move_frog ###

 def gameover_screen(self):
  self.label2 = tk.Label(text="Game over! Your score was: " + str(self.score))
  self.label2.pack()
 ### end of gameover_screen ###

 def update_world(self):
  # update the internal timer
  self.updateticks += 1

  # check for loss conditions
  if((self.timer == 0) or self.hit_by_car() == True or self.in_water() == True or self.home_twice() == True or self.in_grass() == True):
   self.process_death()
   return

  # credit good moves up
  if(self.movedup == True):
   self.score += self.pointsforup
   self.highest = self.frogposition[1]
   self.movedup = False

  # check for win condition
  if(self.at_home() == True):
   self.process_victory()
   return

  # check for total win
  if(self.all_done() == True):
   self.process_win()
   return

  # update the positions of the cars, logs, and turtles
  self.update_positions()
 ### end of update_world ###

 def all_done(self):
  if(len([x for x in self.homes if x[1]==False])==0):
   return True
  return False
 ### end of all_done ###

 def process_win(self):
  self.gameover = True
  return
 ### end of process_win ###

 def process_death(self):
  self.lives -= 1
  if(self.lives < 1):
   self.gameover = True
   return
  self.frogposition[0] = self.frogstart[0]
  self.frogposition[1] = self.frogstart[1]
  self.highest = 12
  self.timer = self.timerstart
 ### end of process_death ###

 def hit_by_car(self):
  for lane in self.lanes:
   if(lane.type != "car"):
    continue
   for car in lane.objects:
    if(car == self.frogposition):
     return True
  return False
 ### end of hit_by_car

 def in_water(self):
  if(self.frogposition[1] < self.waterbordertop or self.frogposition[1] > self.waterborderbottom):
   return False
  for lane in self.lanes:
   if(lane.type == "turtle"):
    for turtle in lane.objects:
     if(turtle == self.frogposition):
      return False
   elif(lane.type == "log"):
    for log in lane.objects:
     if(log == self.frogposition):
      return False
  return True
 ### end of in_water

 def home_twice(self):
  for h in self.homes:
   if(h[0] == self.frogposition and h[1] == True):
    return True
  return False
 ### end of home_twice

 def in_grass(self):
  if(self.frogposition[1] == 0 and self.at_home() == False):
   return True
  return False
 ### end of in_grass

 def at_home(self):
  for h in self.homes:
   if(h[0] == self.frogposition):
    return True
  return False
 ### end of at_home ###

 def process_victory(self):
  self.score += self.pointsforhome
  if(self.bugposition == self.frogposition):
   self.score += self.pointsforbug
  for h in self.homes:
   if (h[0] == self.frogposition):
    h[1] = True
    break
  self.timer = self.timerstart
  self.frogposition[0] = self.frogstart[0]
  self.frogposition[1] = self.frogstart[1]
  self.highest = 12
  self.speedup += self.speedchange
 ### end of process_victory ###

 def init_lanes(self):
  random.seed()
  self.lanes = []
  self.lanes.append(Lane(row=11, lanetype="car", maxnumber=10, replenish=0.1, direction=1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=10, lanetype="car", maxnumber=8, replenish=0.2, direction=-1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=9, lanetype="car", maxnumber=5, replenish=0.6, direction=1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=8, lanetype="car", maxnumber=9, replenish=0.4, direction=-1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=7, lanetype="car", maxnumber=6, replenish=0.3, direction=1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=5, lanetype="turtle", direction=-1, length=3, gap=4, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=4, lanetype="log", direction=1, length=3, gap=3, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=3, lanetype="log", direction=-1, length=8, gap=9, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=2, lanetype="turtle", direction=1, length=2, gap=6, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
  self.lanes.append(Lane(row=1, lanetype="log", direction=-1, length=4, gap=4, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
 ### end of init_lanes

 def init_special(self):
  self.bugposition = [2, 0]
  self.buglastupdate = 0
  self.bugspeed = random.randint(self.minbugspeed, self.maxbugspeed)
  self.homes = [[[2, 0], False], [[7, 0], False], [[12, 0], False], [[17, 0], False], [[22, 0], False]]
 ### end of init_special ###

 def update_positions(self):
  if(self.updateticks - self.buglastupdate >= self.bugspeed - self.speedup):
   self.buglastupdate = self.updateticks
   while(True):
    freeslots = [x for x in self.homes if x[1] == False]
    if(len(freeslots)==0):
     self.bugposition = [-1,-1]
     break
    if(len(freeslots)==1):
     self.bugposition = freeslots[0][0]
     break
    newhomeindex = random.randint(0, 4)
    if(self.homes[newhomeindex][0] != self.bugposition and self.homes[newhomeindex][1] == False):
     self.bugposition = self.homes[newhomeindex][0]
     break

  for lane in self.lanes:
   lanemovedfrog=False
   if(self.updateticks - lane.lanelastupdate >= lane.speed - self.speedup):
    lane.lanelastupdate = self.updateticks
   else:
    continue
   for o in lane.objects:
    if(o == self.frogposition and lanemovedfrog==False):
     self.move_frog(self.directions[int(0.5*lane.direction + 2.5)])
     lanemovedfrog=True
    o[0] += lane.direction
    if((o[0] < 0) or (o[0] >= self.width)):
     lane.objects.remove(o)
   if(lane.type == "car" and len(lane.objects) < lane.maxnumber and random.random() < lane.replenish):
    lane.objects.append([int((self.width-1)/2 - (self.width-1)*lane.direction/2), lane.row])
   if(lane.type == "log" or lane.type == "turtle"):
    if(lane.direction == 1):
     start = min([x[0] for x in lane.objects])
     nxt = min([x for x in range(start, self.width) if (len([y for y in lane.objects if y[0] == x]) == 0)])
     if(start >= lane.gap or (nxt - start) < lane.length):
      lane.objects.append([0, lane.row])
    else:
     start = max([x[0] for x in lane.objects])
     nxt = max([x for x in range(start, -1, -1) if (len([y for y in lane.objects if y[0] == x]) == 0)])
     if(self.width - start - 1 >= lane.gap or (start - nxt) < lane.length):
      lane.objects.append([self.width - 1, lane.row])
   lane.objects.sort()
 ### end of update_positions ###

 def draw_world(self):
  self.text.state = "normal"
  self.text.delete('1.0', str(self.width + 1) + '.' + '0')
  drawstr = ""
  # draw home row
  newstr = self.symbols["grass"] * self.width
  for h in self.homes:
   if(h[1] == False):
    if(self.bugposition == h[0]):
     newstr = self.str_replace(newstr, h[0][0], self.symbols["bug"])
    else:
     newstr = self.str_replace(newstr, h[0][0], self.symbols["freehome"])
   else:
    newstr = self.str_replace(newstr, h[0][0], self.symbols["fullhome"])
  drawstr += newstr
  drawstr += "\n"

  # draw water rows
  for index in range(self.waterborderbottom - self.waterbordertop + 1):
   newstr = self.symbols["water"] * self.width
   for lane in self.lanes:
    if(lane.row == index + self.waterbordertop):
     for o in lane.objects:
      if(lane.type == "log"):
       newstr = self.str_replace(newstr, o[0], self.symbols["log"])
      elif(lane.type == "turtle"):
       newstr = self.str_replace(newstr, o[0], self.symbols["turtle"])
   drawstr += newstr
   drawstr += "\n"

  # draw safe row
  drawstr += self.symbols["saferow"] * self.width
  drawstr += "\n"

  # draw car rows
  for index in range(len([l for l in self.lanes if l.type == "car"])):
   newstr = self.symbols["road"] * self.width
   for lane in self.lanes:
    if(lane.row == self.waterborderbottom + 2 +index):
     for o in lane.objects:
      if(lane.direction == 1):
       newstr = self.str_replace(newstr, o[0], self.symbols["rightcar"])
      elif(lane.direction == -1):
       newstr = self.str_replace(newstr, o[0], self.symbols["leftcar"])
   drawstr += newstr
   drawstr += "\n"

  # draw safe row
  drawstr += self.symbols["saferow"] * self.width

  # do actual drawing
  self.text.insert('1.0', drawstr)

  # draw frog
  self.text.delete(str(1 + self.frogposition[1]) + '.' + str(self.frogposition[0]))
  self.text.insert(str(1 + self.frogposition[1]) + '.' + str(self.frogposition[0]), self.symbols["frog"])

  # apply colors
  for sprite in self.sprites.keys():
   self.highlight_pattern(sprite, self.sprites[sprite])

  # turn off editability
  self.text.state = "disabled"
 ### end of draw_world ###

 def str_replace(self, targetstr, index, char):
  return targetstr[:index] + char + targetstr[index+1:]
 ### end of str_replace ###

 def highlight_pattern(self, sprite, tag):
  start = self.text.index("1.0")
  end = self.text.index("end")
  self.text.mark_set("matchStart", start)
  self.text.mark_set("matchEnd", start)
  self.text.mark_set("searchLimit", end)
  count = tk.IntVar()
  while True:
   index = self.text.search(sprite, "matchEnd", "searchLimit", count=count, regexp=False)
   if(index == ""):
    break
   self.text.mark_set("matchStart", index)
   self.text.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
   self.text.tag_add(tag, "matchStart","matchEnd")
 ### end of highlight_pattern ###
### end of Frogger class ###

# Run the game!!!
frogger = Frogger()

2
Tôi nghĩ vấn đề đến từ việc cập nhật màn hình. Nếu chương trình của bạn chạy ở tốc độ 60fps, phải mất khoảng 16ms để làm. Điều này có nghĩa là vòng lặp chính của bạn không thể chạy cứ sau 1ms. (Đây là logic chung, nhưng tôi không có chuyên môn với Tkinter hoặc các hệ thống GUI khác)
xem phần

Có thể đáng để hỏi về SO về điều này. Xin vui lòng gửi một liên kết ở đây nếu bạn làm.

1
Tôi đã nghe lời khuyên của bạn và hỏi về SO: stackoverflow.com/questions/23999478/ trộm Tốc độ làm mới màn hình được đặt ở mỗi 20 lần cập nhật, tốc độ cứ sau 20ms, hoặc tốc độ 50fps. Điều này có vẻ như dễ dàng đối với bất kỳ máy tính hiện đại nào.
RT

2
Dựa trên câu trả lời SO, tôi đã thay đổi chương trình để sử dụng bộ hẹn giờ 20 ms. Tôi cũng đã sửa một vài lỗi khác trong lúc này. Nếu có đủ sự quan tâm, tôi sẽ tìm cách thêm màu sắc để làm cho ASCII dễ nhìn hơn. Hãy bình luận với các đề xuất, tôi sẽ làm hết sức mình để thực hiện chúng.
RT

Điều này hoạt động thực sự tốt (đảm bảo chạy với python3 filenamechứ không phải python filename). Tôi đã trao cho bạn tiền thưởng vì câu trả lời khác chưa kết thúc

1

C ++ 1710

Tôi bắt đầu một phiên bản console ASCII. Con ếch có thể di chuyển. Vẫn làm việc theo yêu cầu khác. Chưa thực hiện phát hiện đối tượng hoặc ghi điểm. Ếch di chuyển với các phím w, a, s, d.

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define P(x) cout<<x<<endl
#define R 13
#define C 25
string bank="=========================";
string water="~~~~~~~~~~~~~~~~~~~~~~~~~";
string road="-------------------------";
string log="LOG";
string car="CAR";
string frog="FROG";
string leaf="LEAF";
string rows[R];
bool gameover=false;
int frogX,frogY;

void insertObject(string obj, int row, int pos)
{
    string tmp=rows[row].erase(pos,obj.size());
    tmp.insert(pos,obj);
    rows[row]=tmp;
}

void newBoard()
{
int r,r2;
for(int i=0;i<R;i++)
{
    r=rand()%2+1;//1-3
    if(i==0||i==6||i==12)
    {
        rows[i]=bank;
    }
    else if(i>0&&i<6)
    {
        rows[i]=water;
        for(int j=0;j<r;j++)
        {
            r2=rand()%21;
            insertObject(log, i, r2);
        }
    }
    else
    {
        rows[i]=road;
        for(int j=0;j<r;j++)
        {
            r2=rand()%21;
            insertObject(car, i, r2);
        }
    }
}
insertObject(frog, 12, (int)(C-4)/2);
frogX=(int)(C-4)/2;
frogY=12;
insertObject(leaf, 0, (int)(C-4)/2);
}

void showBoard()
{
#ifdef WIN32
system("cls");
#else
system("clear");
#endif
for(int i=0;i<R;i++)
{
    P(rows[i]);
}
}

void playGame()
{
char c;
int i=0;
while(!gameover)
{
cin>>c;
switch(c)
{
case 'a':
    if(frogX!=0)frogX--;
    break;
case 'w':
    if(frogY!=0)frogY--;
    break;
case 'd':
    if(frogX<21)frogX++;
    break;
case 's':
    if(frogY!=12)frogY++;
    break;
default:
    break;
}
insertObject(frog, frogY, frogX);
showBoard();
i++;
if(i>12) gameover=true;
}
}

int main()
{
    srand(time(0));
    char play='y';
    while(play=='y')
    {
        newBoard();
        showBoard();
        playGame();
        P("Play Again (y/n)?");
        cin>>play;
    }

    return 0;
}

#define s stringđể chơi gôn nhiều hơn một chút (lưu ý: điều này dường như ngắn hơn một char typedef string s;) Hoặc bạn có thể làm #define t typedef, sau đó t string s;, mặc dù tôi không biết liệu điều đó có hiệu quả hay không

ngoài ra bạn có thể muốn sử dụng ++ithay vìi++
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.