好的,这里有一个相当复杂的代码高尔夫挑战:实现一个里弗西游戏(Othello)。
在尽可能少的字符中这样做。
会话应该如下所示:
abcdefgh
1
2
3
4 wb
5 bw
6
7
8
b>d3
abcdefgh
1
2
3 b
4 bb
5 bw
6
7
8 发布于 2009-10-19 06:54:25
Perl,408个字符
这是Perl,现在减少到408个字符。可以用一种更小的方法再砍25个字符来声明获胜者(比如说"B"而不是"Winner: Black\n")。前两个换行符是重要的,其他的是为了可读性而包括的。
sub O{2&$B[$q+=$_]*$%}sub A{grep{$q=$=;$"=''while&O;$B[$q]*O$q=$=}$B[$=]?():@d}
sub F{$B[$q]=$%;O&&&F}sub D{print'
',a..h,$/,(map{($e="@B[$_*9+1..$_*9+8]
")=~y/012/ bw/;$_,$e}1..8),@_}
@d=map{$_,-$_}1,8..10;@B=(@z=(0)x40,$%=2,1,(0)x7,1,2,@z);
for$!(%!){$%^=3;for$=(9..80){$=%9*A&&do{{D$%-2?b:w,"> ";
$_=<>;$==(/./g)[1]*9-96+ord;A||redo}F$q=$=for A;last}}}
$X+=/1/-/2/for@B;D"Winner: ",$X<0?White:$X?Black:None,$/@B拿着棋盘。$B[$i*9+$j]指行$i (1..8)和列$j (1..8)
@d是由8个有效方向组成的列表
O是一种方便的方法。它将$q增量为$_ (当前方向),如果$B[$q]处的棋子属于当前玩家的对手,则返回非零值。
F处理当前方向的翻转块,$_
A检查当前玩家是否可以在$B[$=]上合法移动,并返回一组可以翻转的方向。
D(@_)绘制板并打印@_
主循环切换$% (当前播放器)并遍历董事会上的位置,为该播放器找到合法的移动。如果发现任何合法移动,请从标准输入读取移动(重复直到输入有效移动)并更新板。
发布于 2009-10-17 16:28:45
编辑2:
再加上一些调整和技巧,我又把124个字符削减到了752个字符:
using C=System.Console;class O{static int[]b=new int[100];static int c=1;static void Main(){b[44]=b[55]=-1;b[45]=b[54]=1;var g=true;while(g){C.WriteLine(" abcdefgh");for(int i=10;i<90;i++){switch(i%10){case 0:C.Write(i/10);break;case 9:C.WriteLine();break;default:C.Write("w b"[b[i]+1]);break;}}C.Write("w b"[c+1]+">");var l=C.ReadLine();if(l.Length>1){int x=l[0]-96,y=l[1]-48;if(x>0&x<9&y>0&y<9&&b[y*10+x]<1)c*=f(y*10+x,1);}g=false;for(int y=10;y<90;y+=10)for(int x=y;x<y+8;)g|=b[++x]==0&&f(x,0)<0;}int s=0;foreach(int p in b)s+=p;C.WriteLine(s==0?"d":s<0?"w":"b");}static int f(int ofs,int y){var x=1;foreach(int d in new int[]{-11,-10,-9,-1,1,9,10,11}){int l=1,o=ofs;while(b[o+=d]==-c)l++;if(b[o]==c&l>1){x=-1;while(y>0&l-->0)b[o-=d]=c;}}return x;}}在压实之前:
using Con = System.Console;
class O {
// Initialise game board, made of ints - 0 is empty, 1 is a black piece, -1 a white.
// Using a 10x10 board, with the outer ring of empties acting as sentinels.
static int[] board = new int[100];
// Color of the current player.
static int currentColor = 1;
static void Main() {
// Set up the four pieces in the middle.
board[44] = board[55] = -1;
board[45] = board[54] = 1;
var legal = true;
while (legal) {
// Print game board.
Con.WriteLine(" abcdefgh");
for (int i = 10; i < 90; i++) {
switch (i % 10) {
case 0: Con.Write(i / 10); break;
case 9: Con.WriteLine(); break;
default: Con.Write("w b"[board[i] + 1]); break;
}
}
// Print input, indicating which color's turn it is.
Con.Write("w b"[currentColor+1] + ">");
// Parse input.
var line = Con.ReadLine();
if (line.Length > 1) {
int x = line[0] - 96, y = line[1] - 48;
// Discard malformed input.
if (x > 0 & x < 9 & y > 0 & y < 9 && board[y * 10 + x] < 1)
// Check if valid move and if so flip and switch players
currentColor *= flip(y * 10 + x, 1);
}
// See if there are any legal moves by considering all possible ones.
legal = false;
for (int y = 10; y < 90; y += 10)
for (int x = y; x < y + 8;)
legal |= board[++x] == 0 && flip(x, 0) < 0;
}
// Calculate final score: negative is a win for white, positive one for black.
int score = 0;
foreach (int piece in board) score += piece;
Con.WriteLine(score == 0 ? "d" : score < 0 ? "w" : "b");
}
// Flip pieces, or explore whether putting down a piece would cause any flips.
static int flip(int ofs, int commitPutDown) {
var causesFlips = 1;
// Explore all straight and diagonal directions from the piece put down.
foreach (int d in new int[] { -11, -10, -9, -1, 1, 9, 10, 11 }) {
// Move along that direction - if there is at least one piece of the opposite color next
// in line, and the pieces of the opposite color are followed by a piece of the same
// color, do a flip.
int distance = 1, o = ofs;
while (board[o += d] == - currentColor) distance++;
if (board[o] == currentColor & distance > 1) {
causesFlips = -1;
while (commitPutDown > 0 & distance-- > 0) board[o -= d] = currentColor;
}
}
return causesFlips;
}
}876字符C#版本:
using C=System.Console;class O{static void Main(){int[]b=new int[100];b[44]=b[55]=2;b[45]=b[54]=1;int c=1;while(true){C.WriteLine(" abcdefgh");for(int i=10;i<90;i++){switch(i%10){case 0:C.Write(i/10);break;case 9:C.WriteLine();break;default:C.Write(" bw"[b[i]]);break;}}bool g=false;for(int y=10;y<90;y+=10)for(int x=1;x<9;x++){g|=(b[x+y]==0&&f(x+y,b,c,false));}if(!g)break;C.Write(" bw"[c]+">");var l=C.ReadLine();if(l.Length>1){int x=l[0]-96,y=l[1]-48,ofs;if(x>0&x<9&y>0&y<9&&b[ofs=y*10+x]==0)if(f(ofs,b,c,true))b[ofs]=c;c=3-c;}}int s=0;for(int y=10;y<90;y+=10)for(int x=1;x<9;x++)switch(b[y+x]){case 1:s++;break;case 2:s--;break;}C.WriteLine(s==0?"d":s<0?"w":"b");}static bool f(int ofs,int[]b,int p,bool c){var x=false;foreach(int d in new int[]{-11,-10,-9,-1,1,9,10,11}){int l=1,o=ofs;while(b[o+=d]==3-p)l++;if(b[o]==p&l>1){x=true;if(c)while(l-->1)b[o-=d]=p;}}return x;}}在压实之前:
using Con = System.Console;
class Othello {
static void Main() {
// Initialise game board, made of ints - 0 is empty, 1 is a black piece, 2 a white.
// Using a 10x10 board, with the outer ring of empties acting as sentinels.
int[] board = new int[100];
// Set up the four pieces in the middle.
board[44] = board[55] = 2;
board[45] = board[54] = 1;
// Color of the current player.
int currentColor = 1;
while (true) {
// Print game board.
Con.WriteLine(" abcdefgh");
for (int i = 10; i < 90; i++) {
switch (i % 10) {
case 0: Con.Write(i / 10); break;
case 9: Con.WriteLine(); break;
default: Con.Write(" bw"[board[i]]); break;
}
}
// See if there are any legal moves by considering all possible ones.
bool legal = false;
for (int y = 10; y < 90; y += 10) for (int x = 1; x < 9; x++) {
legal |= (board[x + y] == 0 && flip(x + y, board, currentColor, false));
}
if (!legal) break;
// Print input, indicating which color's turn it is.
Con.Write(" bw"[currentColor] + ">");
// Parse input.
string l = Con.ReadLine();
if (l.Length > 1) {
int x = l[0] - 96, y = l[1] - 48;
int ofs;
// Discard malformed input.
if (x > 0 & x < 9 & y > 0 & y < 9 && board[ofs = y * 10 + x] == 0)
// Check if valid move & flip if it is - if not, continue.
if (flip(ofs, board, currentColor, true))
// Put down the piece itself.
board[ofs] = currentColor;
// Switch players.
currentColor = 3 - currentColor;
}
}
// Calculate final score: negative is a win for white, positive one for black.
int score = 0;
for (int y = 10; y < 90; y += 10) for (int x = 1; x < 9; x++)
switch (board[y + x]) {
case 1: score++; break;
case 2: score--; break;
}
Con.WriteLine(score == 0 ? "d" : score < 0 ? "w" : "b");
}
/** Flip pieces, or explore whether putting down a piece would cause any flips. */
static bool flip(int ofs, int[] board, int playerColor, bool commitPutDown) {
bool causesFlips = false;
// Explore all straight and diagonal directions from the piece put down.
foreach (int d in new int[] { -11, -10, -9, -1, 1, 9, 10, 11 }) {
// Move along that direction - if there is at least one piece of the opposite color next
// in line, and the pieces of the opposite color are followed by a piece of the same
// color, do a flip.
int distance = 1, o = ofs;
while (board[o += d] == 3 - playerColor) distance++;
if (board[o] == playerColor & distance > 1) {
causesFlips = true;
if (commitPutDown) while (distance-- > 1) board[o -= d] = playerColor;
}
}
return causesFlips;
}
}我使用int100而不是char1010来简化循环和比较。其中有很多小技巧,但除此之外,它基本上与原始Java代码相同。
编辑:
编辑器显示了一些奇怪的"Col“值,但是您应该看看"Ch”值.不是943个字符,是876个.
发布于 2009-10-20 08:06:07
C++,672个字符
这是我的版本。它的重量为672个字符,包括换行符:
#include <iostream>
#define F for
#define G F(i p=9;p<90;++p)
#define R return
#define C std::cout
typedef int i;i b[100];i f(i p, i s, i d){i t=0;i q[]={-11,-10,-9,-1,1,9,10,11};F(i o=0;o<8;++o){i c=p+q[o];F(;b[c]==-s;c+=q[o]);if(b[c]==s)F(--t;c!=p;c-=q[o],++t)if(d)b[c]=s;}R t;}i h(i s){G if(!b[p]&&f(p,s,0))R 1;R 0;}i main(){F(i p=0;p<100;++p)b[p]=p<10||p>89||!(p%10%9)?2:0;b[44]=b[55]=-1;b[45]=b[54]=1;i s=1;F(;;){C<<" abcdefgh";G C<<(char)(p%10?"w b\n"[b[p]+1]:'0'+p/10);s=h(s)?s:-s;if(!h(s)){s=-34;G s+=b[p];C<<(s<0?'s':s?'b':'d')<<'\n';R 0;}i p=0;F(;p<9||p>90||b[p]||!f(p,s,1);){C<<"w b"[s+1]<<">";std::string m;std::cin>>m;p=m[0]-'`'+(m[1]-'0')*10;}b[p]=s;s=-s;}}https://stackoverflow.com/questions/1582359
复制相似问题