1/*	$NetBSD: human.cc,v 1.4 2021/12/05 09:22:45 rillig Exp $	*/
2
3/*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Human interface for dots, using rogue-like keys.
34 */
35
36#include "defs.h"
37RCSID("$NetBSD: human.cc,v 1.4 2021/12/05 09:22:45 rillig Exp $")
38
39#include "human.h"
40#include "board.h"
41#include "box.h"
42#include "ttyscrn.h"
43
44#define CONTROL(a) ((a) & 037)
45
46extern GAMESCREEN *sc;
47
48HUMAN::HUMAN(const char c) :
49    PLAYER(c),
50    _curx(0),
51    _cury(1)
52{
53}
54
55void HUMAN::play(const BOARD& b, size_t& y, size_t& x, int& dir)
56{
57    int mv;
58    b.setpos(_cury, _curx);
59
60    for (;;) {
61	switch (mv = b.getmove()) {
62	case 'h': case 'H':
63	    _curx -= 2;
64	    break;
65
66	case 'l': case 'L':
67	    _curx += 2;
68	    break;
69
70	case 'k': case 'K':
71	    _cury -= 2;
72	    break;
73
74	case 'j': case 'J':
75	    _cury += 2;
76	    break;
77
78	case 'u': case 'U':
79	    _curx += 1;
80	    _cury -= 1;
81	    break;
82
83	case 'y': case 'Y':
84	    _curx -= 1;
85	    _cury -= 1;
86	    break;
87
88	case 'b': case 'B':
89	    _curx -= 1;
90	    _cury += 1;
91	    break;
92
93	case 'n': case 'N':
94	    _curx += 1;
95	    _cury += 1;
96	    break;
97
98	case 'q': case 'Q':
99	    // Cleanup
100	    delete sc;
101	    exit(0);
102
103	case CONTROL('L'): case CONTROL('R'):
104	    b.clean();
105	    b.paint();
106	    break;
107
108	case ' ':
109	    {
110		x = _curx / 2;
111		y = _cury / 2;
112
113		if (_cury & 1) {
114		    if (_curx == 0)
115			dir = BOX::left;
116		    else {
117			x--;
118			dir = BOX::right;
119		    }
120		}
121
122		if (_curx & 1) {
123		    if (_cury == 0)
124			dir = BOX::top;
125		    else {
126			y--;
127			dir = BOX::bottom;
128		    }
129		}
130	    }
131	    return;
132
133	default:
134	    break;
135	}
136
137        // We add 2 before the comparison to avoid underflow
138	if ((2 + _curx) - (_curx & 1) < 2)
139	    _curx = (b.nx() * 2) + (_curx & 1);
140	if (_curx >= (b.nx() * 2) + 1)
141	    _curx = (_curx & 1);
142
143	if ((2 + _cury) - (_cury & 1) < 2)
144	    _cury = (b.ny() * 2) + (_cury & 1);
145	if (_cury >= (b.ny() * 2) + 1)
146	    _cury = (_cury & 1);
147
148	b.setpos(_cury, _curx);
149    }
150}
151