क्लासिक साँप गेम को फिर से बनाएँ


11

यह चुनौती है कि संभव के रूप में कुछ बाइट्स का उपयोग करके क्लासिक स्नेक गेम बनाया जाए।

यहाँ आवश्यकताएँ हैं:

  • खेल को एक विशिष्ट 2-आयामी लेआउट में लागू किया जाना चाहिए। साँप नक्शे की सीमा के भीतर काफी बढ़ने में सक्षम होना चाहिए (इसका वास्तव में मतलब है, अपने नक्शे को बहुत छोटा न करें, यहां अपने विवेक का उपयोग करें)।
  • एक उपयोगकर्ता आपके चयन की कुंजियों का उपयोग करके सांप को स्थानांतरित कर सकता है, हालांकि, साँप अपने आप को दोगुना नहीं कर सकता है (उदाहरण के लिए यदि यह पश्चिम जा रहा है तो यह पूर्व या उत्तर की ओर जाने के बिना पूर्व में नहीं जा सकता है)। एक सांप को सभी 4 दिशाओं में यात्रा करने में सक्षम होना चाहिए: ऊपर, नीचे, बाएं, दाएं (उत्तर, दक्षिण, पश्चिम, पूर्व)।
  • साँप लंबाई 1 के रूप में शुरू होता है, हर बार जब वह "भोजन" वस्तु खाता है तो वह लंबाई में +1 बढ़ता है
  • खाद्य वस्तुओं को साँप के कब्जे वाले स्थानों के अलावा बेतरतीब ढंग से रखा जाता है
  • यदि सांप खुद को मारता है या दीवार खेल खत्म हो जाती है
  • जब खेल को समाप्त कर दिया गया है तो शाब्दिक "स्कोर: [स्कोर]" प्रदर्शित होता है जहां [स्कोर] खेल के दौरान खाए जाने वाले खाद्य पदार्थों की संख्या है। इसलिए, उदाहरण के लिए, यदि सांप ने 4 "खाद्य पदार्थ" खाए हैं (और इसलिए उसकी लंबाई 5 है) जब खेल समाप्त होता है, तो "स्कोर: 4" मुद्रित किया जाएगा।
  • जब तक वे आपके कोड में स्पष्ट रूप से परिभाषित नहीं किए जाते हैं, तब तक कोई संपीड़न एल्गोरिदम नहीं।

यहाँ मेरा समाधान, 908 बाइट्स, पायथन 2.7 है

import random as r
import curses as c
def g(s,w,l):
 while 1:
  p=[r.randrange(0,w),r.randrange(0,l)]
  for l in s:
   if l==p:continue
  return p
s=[]
d=[0,1]
p=k=n=0
e=100
v={65:[-1,0],66:[1,0],68:[0,-1],67:[0,1]}
z=c.initscr()
w,l=z.getmaxyx()[0],z.getmaxyx()[1]
c.noecho()
z.clear()
x=g(s,w,l)
s.append([w/2,l/2])
z.nodelay(1)
q=lambda h,i:range(h,len(i))
while k!=101:
 k=z.getch()
 if k in v and not (d[0]==(v[k][0]*-1) and d[1]==(v[k][1]*-1)):d=v[k]
 f=[0,0]
 for i in q(0,s):
  if i == 0:
   f=[s[i][0],s[i][1]]
   s[i][0]+=d[0]
   s[i][1]+=d[1]
  else:s[i],f=f,s[i]
 if s[0]==x:
  n+=1
  s.append(f)
  x=g(s,w,l)
 z.clear()
 if s[0][0]>=w or s[0][1]>=l or s[0][0]<0 or s[0][1]<0:break
 for i in q(1,s):
  if s[0] == s[i]: k = 101
 for i in q(0,s):z.addch(s[i][0],s[i][1],"X")
 z.addch(x[0],x[1],"O")
 z.move(0,0)
 z.refresh()
 if d[1]!=0:c.napms(e/2)
 else:c.napms(e)
c.endwin()
print 'Score: %s'%n


1
@ कुछ लोगों को टर्मिनलों तक सीमित रहना पसंद नहीं है।
ग्रिफिन

अगर सांप की लंबाई = 1 है तो क्या 'सांप डबल बैक नहीं कर सकता' नियम लागू होता है?
पॉल प्रेस्टिज

@ तुल्यकालित, हाँ यह करता है। हर समय, साँप केवल (सही मायने में) दो तरीके छोड़ सकते हैं, बाएं और दाएं।
mjgpy3

जवाबों:


2

रूबी 1.9 + एसडीएल (341 324 316)

यहां SDL लाइब्रेरी का उपयोग करके रूबी संस्करण में पहला प्रयास किया गया है। मैं 6 वर्णों को बचा सकता हूं यदि मुझे -rsdlआवश्यकता कथन के बजाय कमांड लाइन पर एसडीएल लाइब्रेरी का उपयोग करने की अनुमति है ।

require'sdl'
f=o=d=3
s=SDL::Screen.open l=32,l,0,0
r=*0..l*l
loop{f==o ?f=(r-$*).sample: $*.shift
/yU/=~"#{e=SDL::Event.poll}"&&(v=e.sym%4)&&d+v!=3&&d=v
$><<"Score #{$*.size}"&&exit if$*.index(n=o+[-1,-l,l,1][d])||n<0||n>=l*l||d%3<1&&n/l!=o/l
$*<<o=n
r.map{|i|s[i%l,i/l]=[[f,*$*].index(i)?0:255]*3}
s.flip
sleep 0.1}

साँप खंडों और भोजन के टुकड़ों को काले पिक्सेल का उपयोग करके दर्शाया गया है, वर्तमान में ग्रिड का आकार 32 * 32 है। आप तीर कुंजी (या वास्तव में किसी भी कुंजी के साथ नियंत्रित कर सकते हैं, कीकोड मॉड 4 दिशा सरणी [LEFT, UP, DOWN, RIGHT]) को अनुक्रमित करता है। मुझे लगता है कि यहां निश्चित रूप से सुधार के लिए जगह है, विशेष रूप से मौत की जाँच में IF बयान।

मैंने पिछले संस्करण में इस पर बहुत सुधार किया है, उम्मीद है कि यह अब और अधिक बारीकी से प्रश्न की भावना से मेल खाता है। एक बात है जो मुझे कल्पना के अनुपालन के लिए ठीक करने की आवश्यकता है, जो यह है कि भोजन वर्तमान में पूंछ के अंदर हो सकता है। फिक्स्ड!

खेल पूरा होने के बाद स्कोर को स्टडआउट करने के लिए प्रिंट करता है।


2

जावा, २३४३ २२३ ९

बिल्कुल संक्षिप्त नहीं है, लेकिन मेरा मानना ​​है कि यह सभी आवश्यकताओं का पालन करता है।

साँप वर्ग

import javax.swing.*;
public class S extends JFrame{
S(){add(new B());setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setSize(320,340);setVisible(true);}
public static void main(String[]a){new S();}}

बोर्ड की कक्षा

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class B extends JPanel implements ActionListener{
int W=300;int H=300;int DS=10;int AD=900;int RP=29;int D=140;int x[]=new int[AD];int y[]=new int[AD];int d;int ax;int ay;boolean l=false;boolean r=true;boolean u=false;boolean dn=false;boolean ig=true;Timer t;Image b;Image a;Image h;
B(){addKeyListener(new T());setBackground(Color.black);ImageIcon id=new ImageIcon(this.getClass().getResource("d.png"));b=id.getImage();ImageIcon ia=new ImageIcon(this.getClass().getResource("a.png"));a=ia.getImage();ImageIcon ih=new ImageIcon(this.getClass().getResource("h.png"));h=ih.getImage();setFocusable(true);i();}
void i(){d=3;for(int z=0;z<d;z++){x[z]=50-z*10;y[z]=50;}l();t=new Timer(D,this);t.start();}
public void p(Graphics g){super.paint(g);if(i){g.drawImage(a,ax,ay,this);for(int z=0;z<d;z++){if(z==0)g.drawImage(h,x[z],y[z],this);else g.drawImage(b,x[z],y[z],this);}Toolkit.getDefaultToolkit().sync();g.dispose();}else{g(g);}}
void g(Graphics g){String ms="Score:";Font sm=new Font("Courier",Font.PLAIN,12);FontMetrics me=this.getFontMetrics(sm);g.setColor(Color.white);g.setFont(sm);g.drawString(ms+d,(W-me.stringWidth(ms)),H);}
void c(){if((x[0]==ax)&&(y[0]==ay)){d++;l();}}
void m(){for(int z=d;z>0;z--){x[z]=x[(z-1)]; y[z]=y[(z-1)];}if(l){x[0]-=DS;}if (r){x[0]+=DS;}if(u){y[0]-=DS;}if(dn){y[0]+=DS;}}
void cc(){for(int z=d;z>0;z--){if((z>4)&&(x[0]==x[z])&&(y[0]==y[z])){ig=false;}}if(y[0]>H){ig=false;}if(y[0]<0){ig=false;}if(x[0]> W){ig=false;}if(x[0]<0){ig=false;}}
void l(){int r=(int)(Math.random()*RP);ax=((r*DS));r=(int)(Math.random()*RP);ay=((r*DS));}
public void actionPerformed(ActionEvent e){if(ig){c();cc();m();}repaint();}
class T extends KeyAdapter{public void keyPressed(KeyEvent e){int k=e.getKeyCode();if((k==KeyEvent.VK_LEFT)&&(!r)){l=true;u=false;dn=false;}if((k==KeyEvent.VK_RIGHT)&&(!l)){r=true;u=false;dn=false;}if((k==KeyEvent.VK_UP)&&(!dn)){u=true;r=false;l=false;}if((k==KeyEvent.VK_DOWN)&&(!u)){dn=true;r=false;l=false;}}}}

स्क्रीनशॉट

सांप का खेल जावा में


टीका

कुछ समय पहले मैंने zetcode नाम की एक वेबसाइट का दौरा किया, जिसने जावा में क्लासिक 2D गेम्स बनाने के लिए कुछ ट्यूटोरियल प्रदान किए। प्रदान किया गया कोड स्नेक गेम के लिए प्रदान किए गए ट्यूटोरियल से बहुत प्रभावित होता है ... मुझे लगता है कि इस समय मैंने क्लासिक गेम को कोड करना शुरू कर दिया है और ट्यूटोरियल को 'टी' के रूप में अनुसरण किया है।

मैं बाद में एक संपादन करूंगा और एक निष्पादन योग्य के लिए एक लिंक जोड़ूंगा ताकि लोग खेल खेल सकें।


संपादन

  • 9/9/12: मैं संसाधन फ़ोल्डर से छवियों को ठीक से लोड करने में असमर्थ हूं। मैं यह साबित करने की कोशिश में इस मुद्दे के माध्यम से काम करना जारी रखूंगा कि मेरा कोड काम करता है और प्रश्न के सभी मानदंडों को पूरा करता है।
  • 9/11/12: मैं संसाधन फ़ाइल से लोड करने के लिए चित्र प्राप्त करना जारी रखना चाहता हूं। मैंने ZetCode ट्यूटोरियल से प्रदान की गई एक तस्वीर जोड़ी।

महान, मैं इसे आज़माने के लिए तत्पर हूं!
mjgpy3

क्या निष्पादन योग्य मार्ग के लिए एक लिंक है :)
Drenai

@BrianBishop क्षमा करें दोस्त, मैंने कभी यह पता नहीं लगाया कि मैं संसाधन फ़ाइल में अपनी छवि फ़ाइलों के साथ गलत तरीके से क्या कर रहा था। सब कुछ संकलन करता है, लेकिन चित्र कभी पॉपअप नहीं करते हैं।
रोब

2

बैश: 537 533 507 अक्षर

C=$COLUMNS;L=$LINES;D=-1;c=9;r=9;z=(9\ 9);l=;h=1;v=;s=1;d=1
t(){ echo -en "\e[$2;$1H$3";}
b(){ ((f=RANDOM%C+1));((g=RANDOM%L+1));for i in "${z[@]}";do [[ $f\ $g = $i ]]&&b;done;t $f $g F;}
echo $'\e[2J';b
while :;do
read -sn1 -t.1 k
case $k in
w|s)((h))&&h=&&v=${D:$k};;
a|d)((v))&&v=&&h=${D:$k};;
esac
((c+=h));((r+=v))
((c==f&&r==g&&++l))&&b
((c<1||r<1||c>C||r>L))&&break
for i in "${z[@]}";do [[ $c\ $r = $i ]]&&break 2;done
t ${z[-1]} \ ;t $c $r X
z=($c\ $r "${z[@]::l}")
done
echo $'\e[2J\e[H'Score: $l

चूँकि यह $COLUMNSऔर $LINESशेल चरों का उपयोग करता है , इसे चलाया जाना चाहिए . snake.sh:। साँप को w/ a/ s/ dकुंजियों से नियंत्रित किया जा सकता है ।

मुझे पता है, clearस्क्रीन को साफ़ करने के लिए इसे आसानी से 493 वर्णों तक कम किया जा सकता है , लेकिन मैं इसे शुद्ध रखना पसंद करता हूं bash, बिना किसी बाहरी उपकरण का उपयोग किए।


बहुत अच्छा समाधान!
mjgpy3 18

1

पायथन 2.7: 869 816 818 817 816 वर्ण

मैंने पिछले कुछ घंटों में एक साथ इसे हैक किया। यह आवश्यकताओं को पूरा करना चाहिए और कुछ अक्षर mjgpy3 के समाधान की तुलना में कम है (कड़ी मेहनत की, लेकिन यह बहुत छोटा नहीं हो सका। अब मैं थक गया हूं)। हैरानी की बात है, pygame की तरह एक खेल विकास पुस्तकालय का उपयोग कर अजगर बहुत सांप नहीं मिला। सुझाव और युक्तियां कि कैसे इसे कम किया जाए, अत्यधिक सराहना की जाती है। मुझे आशा है कि यह बहुत गूढ़ नहीं है।

यह परिणाम है:

import pygame as p
from random import randint as r
p.init();l=20
c=p.time.Clock()
dp=p.display;w=p.display.set_mode((500,)*2)
C=p.Color;b=C(0,0,0);g=C(0,99,0)
D=(0,1);U=(0,-1);L=(-1,0);R=(1,0)
S=[R];d=R;n=[]
O=lambda t:{U:D,R:L,D:U,L:R}[t]
def Q(e):print "Score: %i"%(len(S)-1);p.quit()
def K(e):global d;_={276:L,273:U,274:D,275:R}.get(e.key,(0,0));d=not _==O(d) and _ or d
def N(S):[p.draw.rect(w,g,[x[0]*l,x[1]*l,l,l]) for x in S+n] 
def M():n=(r(0,24),r(0,24));return n not in S and n or M()
A=lambda s,o:tuple(x+y for x,y in zip(s,o))
n=[M()] 
while True:
 w.fill(b);[{12:Q,2:K}.get(e.type,lambda e:e)(e) for e in p.event.get()]
 if not (0<=S[-1][0]<25 and 0<=S[-1][1]<25) or A(S[-1],d) in S: Q(e) 
 if A(S[-1],d) in n: S.append(A(S[-1],d));n=[M()]
 else: S.append(A(S[-1],d));S.pop(0)
 N(S);dp.update();c.tick(6)

संपादित करें: मैं इसे 816 बाइट्स तक कम कर सकता हूं, याय! :) स्कोर तय किया

EDIT2: गलती से गलत संस्करण को विस्थापित कर दिया

यहाँ एक टिप्पणी संस्करण है:

import pygame as p
from random import randint as r

# initialize pygame
p.init()

# the game consists of 25*25 blocks,with each block 20*20 pixels
l=20

# initialize the main loop clock
c=p.time.Clock()

# open the window
dp=p.display;w=p.display.set_mode((500,)*2)

# define black and green colors
C=p.Color;b=C(0,0,0);g=C(0,99,0)

# Directions of the snake: down, up, left, right
D=(0,1);U=(0,-1);L=(-1,0);R=(1,0)

# S is the snake, d is the current direction and n is the array of foods
S=[R];d=R;n=[]

# get the opposite direction of a direction to forbid double backing
O=lambda t:{U:D,R:L,D:U,L:R}[t]

# print the score and quit
def Q(e):print "Score: %i"%(len(S)-1);p.quit()

# update the direction (this is a key press handler)
def K(e):global d;_={276:L,273:U,274:D,275:R}.get(e.key,(0,0));d=not _==O(d) and _ or d

# draw the snake and food boxes
def N(S):[p.draw.rect(w,g,[x[0]*l,x[1]*l,l,l]) for x in S+n]

# place new food on the map not colliding with the snake
def M():n=(r(0,24),r(0,24));return n not in S and n or M()

# A((1,1), (-2, 1)) -> (-1,2)
A=lambda s,o:tuple(x+y for x,y in zip(s,o))

# initialize food array
n=[M()]

while True:
 # fill the screen black
 w.fill(b)
 # get quit or key press events and execute the event handlers
 [{12:Q,2:K}.get(e.type,lambda e:e)(e) for e in p.event.get()]

 # check if snake hits map boundaries or itself
 if not (0<=S[-1][0]<25 and 0<=S[-1][1]<25) or A(S[-1],d) in S: Q(e)

 # check if snake is eating food at the moment and append one to the snake's length
 if A(S[-1],d) in n: S.append(A(S[-1],d));n=[M()]

 # move the snake in the current direction
 else: S.append(A(S[-1],d));S.pop(0)

 # draw the map and limit the main loop to 6 frames per second
 N(S);dp.update();c.tick(6)

मुझे यह त्रुटि संदेश "खंडन दोष (कोर डंप किया गया)" मिलता रहा। और ऐसा लगता है कि स्कोर 1 से दूर है (वास्तव में बहुत बड़ी बात नहीं है। हालांकि बहुत अच्छा जवाब।
mjgpy3

2
धन्यवाद :) मुझे वह सेग्मेंट फालतू मैसेज भी मिल गया। अभी तक यह पता नहीं चला। स्कोर निश्चित किया और आकार कम किया :) यह मजेदार है।
स्टेफ्रीक

1
आप हरे रंग को गहरा बना सकते हैं, 255 के बजाय, 99 का उपयोग कर सकते हैं, फिर वह एक बाइट ले जाएगा
KrystosTheOverlord

@KrystosTheOverlord hahah हाँ अच्छा बिंदु: डी
स्टेफ्रीक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.