return any;
}
+ExtFunc int GlanceFunc(int scr, int y, int x, BlockType type, void *data)
+{
+ PlotBlock1(scr, y, x, type);
+ return 0;
+}
+
ExtFunc int PlotFunc(int scr, int y, int x, BlockType type, void *data)
{
SetBlock(scr, y, x, type);
return result;
}
-ExtFunc int RotatePiece(int scr)
+ExtFunc int RotatePiece(int scr, int dir)
{
int result;
EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
- result = ShapeFits(curShape[scr]->rotateTo, scr, curY[scr], curX[scr]);
+ result = ShapeFits(dir ? curShape[scr]->rotateTo : curShape[scr]->rotateFrom,
+ scr, curY[scr], curX[scr]);
if (result)
- curShape[scr] = curShape[scr]->rotateTo;
+ curShape[scr] = dir ? curShape[scr]->rotateTo : curShape[scr]->rotateFrom;
PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
return result;
}
};
#endif
-static void PlotBlock1(int scr, int y, int x, BlockType type);
+ExtFunc void PlotBlock1(int scr, int y, int x, BlockType type);
static MyEventType KeyGenFunc(EventGenRec *gen, MyEvent *event);
static EventGenRec keyGen =
else
boardXPos[scr] = boardXPos[scr - 1] +
2 * boardWidth[scr - 1] + 3;
+ if (scr == 1)
+ boardXPos[scr] += 24;
boardYPos[scr] = 22;
- if (statusXPos < boardXPos[scr] + 2 * boardWidth[scr] + 3)
- statusXPos = boardXPos[scr] + 2 * boardWidth[scr] + 3;
+ statusXPos = 2 * boardWidth[0] + 3;
+// if (statusXPos < boardXPos[scr] + 2 * boardWidth[scr] + 3)
+// statusXPos = boardXPos[scr] + 2 * boardWidth[scr] + 3;
for (y = boardVisible[scr] - 1; y >= 0; --y) {
move(boardYPos[scr] - y, boardXPos[scr] - 1);
addch('|');
{
}
-static void PlotBlock1(int scr, int y, int x, BlockType type)
+ExtFunc void PlotBlock1(int scr, int y, int x, BlockType type)
{
int colorIndex = abs(type);
standout();
}
- addstr(type > 0 ? "[]" : "$$");
+ addstr(type ? "[]" : "$$");
standend();
}
}
ExtFunc void ShowDisplayInfo(void)
{
move(statusYPos - 9, statusXPos);
- printw("Seed: %d", initSeed);
- clrtoeol();
+ printw("Seed: %010d", initSeed);
move(statusYPos - 8, statusXPos);
- printw("Speed: %dms", speed / 1000);
- clrtoeol();
+ printw("Speed: %dms ", speed / 1000);
if (robotEnable) {
move(statusYPos - 6, statusXPos);
if (fairRobot)
addstr("Controlled by a fair robot");
else
addstr("Controlled by a robot");
- clrtoeol();
+// clrtoeol();
}
if (opponentFlags & SCF_usingRobot) {
move(statusYPos - 5, statusXPos);
addstr("The opponent is a fair robot");
else
addstr("The opponent is a robot");
- clrtoeol();
+// clrtoeol();
}
}
+ExtFunc void ShowScore(int scr, int totalDrops, int totalLines, int totalAdds)
+{
+ float timer;
+ move(6, statusXPos); addstr("Next: ");
+ move(7, statusXPos + 6); addstr(" ");
+ ShapeIterate(nextShape[scr], scr,
+ ShapeToNetNum(nextShape[scr]) == 15 ? 15 : 16, statusXPos/2 + 4,
+ 1, GlanceFunc, NULL);
+ move(statusYPos - 20 + 1, statusXPos);
+ timer = CurTimeval() / 1e6;
+ printw("Lines: %05d", totalLines);
+ if (timer > 4)
+ printw(" (%.1f ppm)", totalDrops * 60 / timer);
+ move(statusYPos - 18, statusXPos);
+ printw("apm: %.1f", totalAdds * 60 / timer);
+ if (totalLines > 0)
+ printw(" (%d%% yield) ", 100 * totalAdds / totalLines);
+}
+
ExtFunc void UpdateOpponentDisplay(void)
{
move(1, 0);
if (pausedByThem)
addstr("Game paused by opponent");
else
- clrtoeol();
+ addstr(" ");
move(statusYPos - 2, statusXPos);
if (pausedByMe)
addstr("Game paused by you");
else
- clrtoeol();
+ addstr(" ");
}
ExtFunc void Message(char *s)
{
static int line = 0;
- move(statusYPos - 20 + line, statusXPos);
+// move(statusYPos - 20 + line, statusXPos);
+ move(statusYPos + 2 + line, 1);
addstr(s); /* XXX Should truncate long lines */
clrtoeol();
line = (line + 1) % 10;
- move(statusYPos - 20 + line, statusXPos);
+// move(statusYPos - 20 + line, statusXPos);
+ move(statusYPos + 2 + line, 1);
clrtoeol();
}
ExtFunc void RefreshScreen(void)
{
+/*
static char timeStr[2][32];
time_t theTime;
time(&theTime);
strftime(timeStr[0], 30, "%I:%M %p", localtime(&theTime));
- /* Just in case the local curses library sucks */
+ // Just in case the local curses library sucks
if (strcmp(timeStr[0], timeStr[1]))
{
move(statusYPos, statusXPos);
}
move(boardYPos[0] + 1, boardXPos[0] + 2 * boardWidth[0] + 1);
refresh();
+*/
+ move(statusYPos, statusXPos);
+ printw("Timer: %.0f ", CurTimeval() / 1e6);
+ move(boardYPos[0] + 1, boardXPos[0] + 2 * boardWidth[0] + 1);
+ refresh();
}
ExtFunc void ScheduleFullRedraw(void)
#include <sys/types.h>
#include <netinet/in.h>
-enum { KT_left, KT_rotate, KT_right, KT_drop, KT_down,
+enum { KT_left, KT_right, KT_rotright, KT_rotleft, KT_drop, KT_down,
KT_toggleSpy, KT_pause, KT_faster, KT_redraw, KT_numKeys };
static char *keyNames[KT_numKeys+1] = {
- "Left", "Rotate", "Right", "Drop", "Down", "ToggleSpy", "Pause",
- "Faster", "Redraw", NULL };
+ "Left", "Right", "RotRight", "RotLeft", "Drop", "Down",
+ "ToggleSpy", "Pause", "Faster", "Redraw", NULL };
static char *gameNames[GT_len] = { "OnePlayer", "ClassicTwo" };
ExtFunc int StartNewPiece(int scr, Shape *shape)
{
- curShape[scr] = shape;
+ if (nextShape[scr]) {
+ curShape[scr] = nextShape[scr];
+ nextShape[scr] = shape;
+ }
+ else
+ curShape[scr] = shape;
curY[scr] = boardVisible[scr] + 4;
curX[scr] = boardWidth[scr] / 2;
- while (!ShapeVisible(shape, scr, curY[scr], curX[scr]))
+ while (!ShapeVisible(curShape[scr], scr, curY[scr], curX[scr]))
--curY[scr];
- if (!ShapeFits(shape, scr, curY[scr], curX[scr]))
+ if (!ShapeFits(curShape[scr], scr, curY[scr], curX[scr]))
return 0;
- PlotShape(shape, scr, curY[scr], curX[scr], 1);
+ PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
return 1;
}
{
MyEvent event;
int linesCleared, changed = 0;
+ int totalDrops = 0, totalLines = 0, totalAdds = 0;
int spied = 0, spying = 0, dropMode = 0;
int oldPaused = 0, paused = 0, pausedByMe = 0, pausedByThem = 0;
long pauseTimeLeft;
RobotCmd(0, "BeginGame\n");
RobotTimeStamp();
}
+ nextShape[scr] = ChooseOption(stdOptions);
while (StartNewPiece(scr, ChooseOption(stdOptions))) {
+ ShowScore(scr, totalDrops, totalLines, totalAdds);
if (robotEnable && !fairRobot)
RobotCmd(1, "NewPiece %d\n", ++pieceCount);
if (spied) {
shapeNum = ShapeToNetNum(curShape[scr]);
data[0] = hton2(shapeNum);
- SendPacket(NP_newPiece, sizeof(data), data);
+ SendPacket(scr, NP_newPiece, sizeof(data), data);
}
for (;;) {
changed = RefreshBoard(scr) || changed;
if (!MovePiece(scr, -1, 0))
goto nextPiece;
else if (spied)
- SendPacket(NP_down, 0, NULL);
+ SendPacket(scr, NP_down, 0, NULL);
break;
case E_key:
p = strchr(keyTable, tolower(event.u.key));
switch(key) {
case KT_left:
if (MovePiece(scr, 0, -1) && spied)
- SendPacket(NP_left, 0, NULL);
+ SendPacket(scr, NP_left, 0, NULL);
break;
case KT_right:
if (MovePiece(scr, 0, 1) && spied)
- SendPacket(NP_right, 0, NULL);
+ SendPacket(scr, NP_right, 0, NULL);
+ break;
+ case KT_rotleft:
+ if (RotatePiece(scr, 0) && spied)
+ SendPacket(scr, NP_rotleft, 0, NULL);
break;
- case KT_rotate:
- if (RotatePiece(scr) && spied)
- SendPacket(NP_rotate, 0, NULL);
+ case KT_rotright:
+ if (RotatePiece(scr, 1) && spied)
+ SendPacket(scr, NP_rotright, 0, NULL);
break;
case KT_down:
if (MovePiece(scr, -1, 0) && spied)
- SendPacket(NP_down, 0, NULL);
+ SendPacket(scr, NP_down, 0, NULL);
+ SetITimer(speed, speed);
break;
case KT_toggleSpy:
spying = (!spying) && (scr2 >= 0);
case KT_drop:
if (DropPiece(scr) > 0) {
if (spied)
- SendPacket(NP_drop, 0, NULL);
- SetITimer(speed, speed);
+ SendPacket(scr, NP_drop, 0, NULL);
+ if (dropModeEnable == 2)
+ SetITimer(speed, 1); //instantdrop
+ else
+ SetITimer(speed, speed);
}
dropMode = dropModeEnable;
break;
netint2 data[1];
data[0] = hton2(pausedByMe);
- SendPacket(NP_pause, sizeof(data), data);
+ SendPacket(scr, NP_pause, sizeof(data), data);
}
paused = pausedByMe || pausedByThem;
if (robotEnable)
}
if (dropMode && DropPiece(scr) > 0) {
if (spied)
- SendPacket(NP_drop, 0, NULL);
+ SendPacket(scr, NP_drop, 0, NULL);
SetITimer(speed, speed);
}
break;
data[1] = hton2(column);
InsertJunk(scr, ntoh2(data[0]), column);
if (spied)
- SendPacket(NP_insertJunk, sizeof(data), data);
+ SendPacket(scr, NP_insertJunk, sizeof(data), data);
+// Message("Opponent added %d lines");
break;
}
case NP_newPiece:
case NP_right:
MovePiece(scr2, 0, 1);
break;
- case NP_rotate:
- RotatePiece(scr2);
+ case NP_rotleft:
+ RotatePiece(scr2, 0);
+ break;
+ case NP_rotright:
+ RotatePiece(scr2, 1);
break;
case NP_drop:
DropPiece(scr2);
nextPiece:
dropMode = 0;
FreezePiece(scr);
- linesCleared = ClearFullLines(scr);
+ totalDrops++;
+ if ((linesCleared = ClearFullLines(scr)) > 0) {
+ totalLines += linesCleared;
+ totalAdds += linesCleared - (linesCleared < 4);
+ }
if (linesCleared > 0 && spied)
- SendPacket(NP_clear, 0, NULL);
+ SendPacket(scr, NP_clear, 0, NULL);
if (game == GT_classicTwo && linesCleared > 1) {
short junkLines;
netint2 data[1];
junkLines = linesCleared - (linesCleared < 4);
data[0] = hton2(junkLines);
- SendPacket(NP_giveJunk, sizeof(data), data);
+ SendPacket(scr, NP_giveJunk, sizeof(data), data);
}
}
gameOver:
standoutEnable = colorEnable = 1;
stepDownInterval = DEFAULT_INTERVAL;
MapKeys(DEFAULT_KEYS);
- while ((ch = getopt(argc, argv, "hHRs:r:Fk:c:woDSCp:i:")) != -1)
+ while ((ch = getopt(argc, argv, "hHRs:r:Fk:c:wodDSCp:i:")) != -1)
switch (ch) {
case 'c':
initConn = 1;
fairRobot = 1;
myFlags |= SCF_fairRobot;
break;
- case 'D':
+ case 'd':
dropModeEnable = 1;
break;
+ case 'D':
+ dropModeEnable = 2;
+ break;
case 'C':
colorEnable = 0;
break;
data[0] = hton4(MAJOR_VERSION);
data[1] = hton4(PROTOCOL_VERSION);
- SendPacket(NP_version, sizeof(data), data);
+ SendPacket(0, NP_version, sizeof(data), data);
if (WaitMyEvent(&event, EM_net) != E_net)
fatal("Network negotiation failed");
memcpy(data, event.u.net.data, sizeof(data));
data[0] = hton4(myFlags);
data[1] = hton4(seed);
data[2] = hton4(stepDownInterval);
- SendPacket(NP_startConn, len, data);
+ SendPacket(0, NP_startConn, len, data);
if (WaitMyEvent(&event, EM_net) != E_net ||
event.u.net.type != NP_startConn)
fatal("Network negotiation failed");
len = strlen(userName)+1;
if (len > sizeof(opponentName))
len = sizeof(opponentName);
- SendPacket(NP_userName, len, userName);
+ SendPacket(0, NP_userName, len, userName);
if (WaitMyEvent(&event, EM_net) != E_net ||
event.u.net.type != NP_userName)
fatal("Network negotiation failed");
#include <errno.h>
#define HEADER_SIZE sizeof(netint2[2])
+#define HEADER_SIZE3 sizeof(netint4[3])
static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event);
static EventGenRec netGen = { NULL, 0, FT_read, -1, NetGenFunc, EM_net };
static char netBuf[64];
-static int netBufSize, netBufGoal = HEADER_SIZE;
+static int netBufSize, netBufGoal = HEADER_SIZE3;
static int isServer, lostConn, gotEndConn;
ExtFunc void InitNet(void)
die("bind");
if (listen(sockListen, 1) < 0)
die("listen");
+
+ // while(1) {
addrLen = sizeof(addr);
- sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen);
- if (sock < 0)
+ if ((sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen)) < 0)
die("accept");
- close(sockListen);
- val2.l_onoff = 1;
- val2.l_linger = 0;
- setsockopt(sock, SOL_SOCKET, SO_LINGER,
- (void *)&val2, sizeof(val2));
- netGen.fd = sock;
- strcpy(opponentHost, "???");
- if (addr.sin_family == AF_INET) {
- host = gethostbyaddr((void *)&addr.sin_addr,
- sizeof(struct in_addr), AF_INET);
- if (host) {
- strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
- opponentHost[sizeof(opponentHost)-1] = 0;
+ fprintf(stderr, "Connection: %s\n", inet_ntoa(addr.sin_addr));
+ // if (!fork()) {
+ close(sockListen);
+ val2.l_onoff = 1;
+ val2.l_linger = 0;
+ setsockopt(sock, SOL_SOCKET, SO_LINGER,
+ (void *)&val2, sizeof(val2));
+ netGen.fd = sock;
+ strcpy(opponentHost, "???");
+ if (addr.sin_family == AF_INET) {
+ host = gethostbyaddr((void *)&addr.sin_addr,
+ sizeof(struct in_addr), AF_INET);
+ if (host) {
+ strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
+ opponentHost[sizeof(opponentHost)-1] = 0;
+ }
}
- }
- AddEventGen(&netGen);
+ AddEventGen(&netGen);
+// close(sock);
+ // exit(0);
+ // }
+// close(sock);
+ // }
isServer = 1;
return 0;
}
static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event)
{
int result;
- short type, size;
- netint2 data[2];
+ short uid, type, size;
+ netint4 data[3];
result = MyRead(sock, netBuf + netBufSize, netBufGoal - netBufSize);
if (result < 0) {
if (netBufSize < netBufGoal)
return E_none;
memcpy(data, netBuf, sizeof(data));
- type = ntoh2(data[0]);
- size = ntoh2(data[1]);
+ uid = ntoh4(data[0]);
+ type = ntoh4(data[1]);
+ size = ntoh4(data[2]);
netBufGoal = size;
if (netBufSize < netBufGoal)
return E_none;
netBufSize = 0;
- netBufGoal = HEADER_SIZE;
+ netBufGoal = HEADER_SIZE3;
event->u.net.type = type;
- event->u.net.size = size - HEADER_SIZE;
- event->u.net.data = netBuf + HEADER_SIZE;
+ event->u.net.size = size - HEADER_SIZE3;
+ event->u.net.data = netBuf + HEADER_SIZE3;
if (type == NP_endConn) {
gotEndConn = 1;
return E_lostConn;
{
}
-ExtFunc void SendPacket(NetPacketType type, int size, void *data)
+ExtFunc void SendPacket(short uid, NetPacketType type, int size, void *data)
{
- netint2 header[2];
+ netint4 header[3];
- header[0] = hton2(type);
- header[1] = hton2(size + HEADER_SIZE);
- if (MyWrite(sock, header, HEADER_SIZE) != HEADER_SIZE)
+ header[0] = hton4(uid);
+ header[1] = hton4(type);
+ header[2] = hton4(size + HEADER_SIZE3);
+ if (MyWrite(sock, header, HEADER_SIZE3) != HEADER_SIZE3)
die("write");
if (size > 0 && data && MyWrite(sock, data, size) != size)
die("write");
if (sock >= 0) {
if (!lostConn) {
- SendPacket(NP_endConn, 0, NULL);
+ SendPacket(0, NP_endConn, 0, NULL);
if (isServer) {
while (!lostConn)
WaitMyEvent(&event, EM_net);
else {
while (!gotEndConn)
WaitMyEvent(&event, EM_net);
- SendPacket(NP_byeBye, 0, NULL);
+ SendPacket(0, NP_byeBye, 0, NULL);
}
}
close(sock);
#define DEFAULT_PORT 9284 /* Very arbitrary */
-#define DEFAULT_KEYS "jkl mspf^l"
+//#define DEFAULT_KEYS "hlkj mspf^l"
+//#define DEFAULT_KEYS "4685 2spf^l"
+#define DEFAULT_KEYS "dcaf b^sp^f^l"
/* Protocol versions */
#define MAJOR_VERSION 1
-#define PROTOCOL_VERSION 3
+#define PROTOCOL_VERSION 4
#define ROBOT_VERSION 1
#define MAX_BOARD_WIDTH 32
E_lostConn, E_robot, E_lostRobot } MyEventType;
typedef enum _NetPacketType { NP_endConn, NP_giveJunk, NP_newPiece,
NP_down, NP_left, NP_right,
- NP_rotate, NP_drop, NP_clear,
+ NP_rotright, NP_rotleft, NP_drop, NP_clear,
NP_insertJunk, NP_startConn,
NP_userName, NP_pause, NP_version,
NP_byeBye } NetPacketType;
} EventGenRec;
typedef struct _Shape {
- struct _Shape *rotateTo;
+ struct _Shape *rotateTo, *rotateFrom;
int initY, initX, mirrored;
Dir initDir;
BlockType type;
EXT GameType game;
EXT int boardHeight[MAX_SCREENS];
EXT int boardVisible[MAX_SCREENS], boardWidth[MAX_SCREENS];
-EXT Shape *curShape[MAX_SCREENS];
+EXT Shape *curShape[MAX_SCREENS], *nextShape[MAX_SCREENS];
EXT int curY[MAX_SCREENS], curX[MAX_SCREENS];
EXT char opponentName[16], opponentHost[256];
EXT int standoutEnable, colorEnable;
#define PreDecl(name, dir) \
static Shape ShapeName(name, dir)
-#define StdShape(name, cmdName, mirror, type, realDir, dir, nextDir) \
- static Shape ShapeName(name, dir) = { &ShapeName(name, nextDir), \
- 0, 0, mirror, D_ ## realDir, type, cmds_ ## cmdName }
+#define StdShape(name, cmdName, mirror, type, realDir, dir, nextDir, prevDir) \
+ static Shape ShapeName(name, dir) = { \
+ &ShapeName(name, nextDir), &ShapeName(name, prevDir), \
+ 0, 0, mirror, D_ ## realDir, type, cmds_ ## cmdName \
+ }
#define FourWayDecl(name, cmdName, mirror, type) \
PreDecl(name, down); \
- StdShape(name, cmdName, mirror, type, left, left, down); \
- StdShape(name, cmdName, mirror, type, up, up, left); \
- StdShape(name, cmdName, mirror, type, right, right, up); \
- StdShape(name, cmdName, mirror, type, down, down, right)
+ PreDecl(name, up); \
+ StdShape(name, cmdName, mirror, type, left, left, up, down); \
+ PreDecl(name, right); \
+ StdShape(name, cmdName, mirror, type, up, up, right, left); \
+ StdShape(name, cmdName, mirror, type, right, right, down, up); \
+ StdShape(name, cmdName, mirror, type, down, down, left, right)
#define TwoWayDecl(name, cmdName, mirror, type) \
PreDecl(name, vert); \
- StdShape(name, cmdName, mirror, type, right, horiz, vert); \
- StdShape(name, cmdName, mirror, type, down, vert, horiz)
+ StdShape(name, cmdName, mirror, type, right, horiz, vert, vert); \
+ StdShape(name, cmdName, mirror, type, down, vert, horiz, horiz)
static Cmd cmds_long[] = { C_back, C_plot, C_forw, C_plot, C_forw, C_plot,
C_forw, C_plot, C_end };
static Cmd cmds_square[] = { C_plot, C_forw, C_left, C_plot, C_forw, C_left,
C_plot, C_forw, C_left, C_plot, C_end };
-static Shape shape_square = { &shape_square, 0, 0, D_up, 0, BT_magenta,
- cmds_square };
+static Shape shape_square = { &shape_square, &shape_square, 0, 0, D_up, 0,
+ BT_magenta, cmds_square };
static Cmd cmds_l[] = { C_right, C_back, C_plot, C_forw, C_plot, C_forw,
C_plot, C_left, C_forw, C_plot, C_end };
-FourWayDecl(l, l, 0, BT_cyan);
+FourWayDecl(l, l, 0, BT_cyan);
FourWayDecl(l1, l, 1, BT_yellow);
static Cmd cmds_t[] = { C_plot, C_forw, C_plot, C_back, C_right, C_forw,
" the game instead of the keyboard\n"
" -F Use fair robot interface\n"
" -s <seed> Start with given random seed\n"
- " -D Drops go into drop mode\n"
+ " -d Drops go into drop mode\n"
" This means that sliding off a cliff after a drop causes\n"
" another drop automatically\n"
+ " -D Instant drop\n"
" -S Disable inverse/bold/color for slow terminals\n"
" -C Disable color\n"
" -H Show distribution and warranty information\n"