Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package bs for openSUSE:Factory checked in at 2026-10-21 21:02:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/bs (Old) and /work/SRC/openSUSE:Factory/.bs.new.2252680 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "bs" Wed Oct 21 21:02:30 2026 rev:4 rq:1386896 version:2.15 Changes: -------- --- /work/SRC/openSUSE:Factory/bs/bs.changes 2025-03-12 15:27:34.975128358 +0100 +++ /work/SRC/openSUSE:Factory/.bs.new.2252680/bs.changes 2026-10-21 21:03:38.638544883 +0200 @@ -1,0 +2,21 @@ +Sun Oct 18 09:20:28 UTC 2026 - Martin Pluskal <[email protected]> + +- Update to 2.15: + * 2.14: fix stack buffer overflow on long usernames: the + login name is now truncated into a LOGIN_NAME_MAX buffer + instead of strcpy into a 40-byte array + * 2.15: upstream packaging fixes: install honors + PREFIX/BINDIR/MANDIR, man page is built from source with + asciidoctor instead of shipping a prebuilt one + * Fully spellchecked manual page and assorted + undefined-behavior fixes (curses/mouse handling, character + classification, computer-AI state reset on new game) +- Add bs-fix-install-paths.patch: install the binary into BINDIR + instead of MANDIR and honor DESTDIR in uninstall +- Add bs-fix-gcc15-errors.patch: fix -Wincompatible-pointer-types + errors with GCC 14 and later +- Spec cleanup: drop Group tag; add missing gcc, make and + rubygem(asciidoctor) BuildRequires; pass PREFIX at install time + and build with optflags; README renamed to README.adoc upstream + +------------------------------------------------------------------- Old: ---- bs-2.13.tar.gz New: ---- bs-2.15.tar.gz bs-fix-gcc15-errors.patch bs-fix-install-paths.patch ----------(New B)---------- New: instead of MANDIR and honor DESTDIR in uninstall - Add bs-fix-gcc15-errors.patch: fix -Wincompatible-pointer-types errors with GCC 14 and later New: classification, computer-AI state reset on new game) - Add bs-fix-install-paths.patch: install the binary into BINDIR instead of MANDIR and honor DESTDIR in uninstall ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ bs.spec ++++++ --- /var/tmp/diff_new_pack.hghUF6/_old 2026-10-21 21:03:39.383576510 +0200 +++ /var/tmp/diff_new_pack.hghUF6/_new 2026-10-21 21:03:39.384576553 +0200 @@ -1,7 +1,7 @@ # # spec file for package bs # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # Copyright (c) 2025 Andreas Stieger <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -18,16 +18,21 @@ Name: bs -Version: 2.13 +Version: 2.15 Release: 0 Summary: Battleships solitaire game with a color interface License: BSD-2-Clause -Group: Amusements/Games/Strategy/Turn Based URL: http://www.catb.org/~esr/bs/ Source0: http://www.catb.org/~esr/%{name}/%{name}-%{version}.tar.gz +Patch0: bs-fix-install-paths.patch +Patch1: bs-fix-gcc15-errors.patch +BuildRequires: %{rubygem asciidoctor} +BuildRequires: gcc BuildRequires: hicolor-icon-theme -BuildRequires: ncurses-devel +BuildRequires: make +BuildRequires: pkgconfig BuildRequires: update-desktop-files +BuildRequires: pkgconfig(ncurses) %description The classic game of Battleships against the computer. Uses character-cell @@ -38,15 +43,15 @@ %autosetup -p1 %build -%make_build +%make_build CFLAGS="%{optflags}" %install -%make_install +%make_install PREFIX=%{_prefix} %suse_update_desktop_file %{name} %files %license COPYING -%doc NEWS.adoc README +%doc NEWS.adoc README.adoc %{_bindir}/%{name} %{_mandir}/man6/%{name}.6%{?ext_man} %{_datadir}/appdata/ ++++++ bs-2.13.tar.gz -> bs-2.15.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/Makefile new/bs-2.15/Makefile --- old/bs-2.13/Makefile 2024-02-13 19:21:24.000000000 +0100 +++ new/bs-2.15/Makefile 2026-03-27 11:43:30.000000000 +0100 @@ -3,15 +3,14 @@ # SPDX-License-Identifier: BSD-2-Clause # SPDX-FileCopyrightText: (C) Eric S. Raymond <[email protected]> -VERSION=$(shell sed -n <NEWS.adoc '/::/s/^\([0-9][^:]*\).*/\1/p' | head -1) +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +DATADIR ?= $(PREFIX)/share +MANDIR ?= $(DATADIR)/man -CC = gcc +VERSION=$(shell sed -n <NEWS.adoc '/::/s/^\([0-9][^:]*\).*/\1/p' | head -1) -# DESTDIR support -DESTDIR = - -bs: bs.c - $(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -o bs bs.c -lncurses +# Rules # Note: to suppress the footers with timestamps being generated in HTML, # we use "-a nofooter". @@ -24,35 +23,56 @@ .adoc.html: asciidoctor -D. -a nofooter -a webfonts! $< +.PHONY: add clean reflow cppcheck spellcheck +.PHONY: install uninstall version dist release refresh + +# Build + +bs: bs.c + $(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -o bs bs.c -lncurses + clean: rm -f bs bs.6 bs*.tar.gz bs*.rpm *~ *.html +# Validate + reflow: @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]") cppcheck: - cppcheck --quiet --template gcc --enable=all --suppress=missingIncludeSystem bs.c + @cppcheck --quiet --template=gcc --enable=all --suppress=checkersReport --suppress=missingIncludeSystem --suppress=redundantContinue --suppress=knownConditionTrueFalse bs.c + +spellcheck: + @spellcheck bs.adoc + +# Install/uninstall # Note: does not install desktop file. install: bs.6 uninstall - install -m 0755 -d $(DESTDIR)/usr/bin - install -m 0755 -d $(DESTDIR)/usr/share/man/man6 + install -m 0755 -d $(DESTDIR)$(BINDIR) + install -m 0755 -d $(DESTDIR)$(MANDIR)/man6 install -m 0755 -d $(DESTDIR)//usr/share/applications/ install -m 0755 -d $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/ install -m 0755 -d $(DESTDIR)/usr/share/appdata - install -m 0755 bs $(DESTDIR)/usr/bin/ - install -m 0644 bs.6 $(DESTDIR)/usr/share/man/man6/ + install -m 0755 bs $(DESTDIR)$(MANDIR)/ + install -m 0644 bs.6 $(DESTDIR)$(MANDIR)/man6/ install -m 0644 bs.desktop $(DESTDIR)/usr/share/applications/ install -m 0644 battleship.png $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/ install -m 0644 bs.adoc $(DESTDIR)/usr/share/appdata/ uninstall: - rm -f /usr/bin/bs /usr/share/man/man6/bs.6 + rm -f $(BINDIR)/bs /usr/share/man/man6/bs.6 + +# Export -SOURCES = README COPYING NEWS.adoc control bs.c Makefile bs.adoc battleship.png bs.desktop +SOURCES = README.adoc COPYING NEWS.adoc control bs.c Makefile bs.adoc battleship.png bs.desktop -bs-$(VERSION).tar.gz: $(SOURCES) bs.6 - tar --transform='s:^:bs-$(VERSION)/:' --show-transformed-names -cvzf bs-$(VERSION).tar.gz $(SOURCES) bs.6 +bs-$(VERSION).tar.gz: $(SOURCES) + mkdir bs-$(VERSION) + cp -r $(SOURCES) bs-$(VERSION) + tar -czf bs-$(VERSION).tar.gz bs-$(VERSION) + rm -fr bs-$(VERSION) + ls -l bs-$(VERSION).tar.gz dist: bs-$(VERSION).tar.gz @@ -62,3 +82,4 @@ refresh: bs.html shipper -N -w version=$(VERSION) | sh -e -x +# end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/NEWS.adoc new/bs-2.15/NEWS.adoc --- old/bs-2.13/NEWS.adoc 2024-02-13 19:21:24.000000000 +0100 +++ new/bs-2.15/NEWS.adoc 2026-03-27 11:43:30.000000000 +0100 @@ -1,5 +1,13 @@ = bs project news = +2.15: 2026-03-27:: + Packaging fixes. + +2.14: 2026-02-06:: + Fully spellchecked manual page + Prevent buffer overflow on long usernames. + Various small changes to avoid undefined behavior. + 2.13: 2024-02-13:: Code cleanup - remove pre-SuSv2 cruft. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/README new/bs-2.15/README --- old/bs-2.13/README 2024-02-13 19:21:24.000000000 +0100 +++ new/bs-2.15/README 1970-01-01 01:00:00.000000000 +0100 @@ -1,38 +0,0 @@ - BS 2.0 - -Battleships is an intrinsically silly game, but I couldn't resist fixing this -sucker. It now has a purely visual interface (you place ships and call for -shots by moving the cursor around the board using the standard yuhjklbn keys). - -The default game now disallows placement of ships so that they touch. A new --c option is available to force the older behavior. - -I also removed the `seemiss' option (now always on) and `ask' (which is only -useful for cheating). And I ifdefed out the ditsy opening screen; if you want -it back, compile with -DPENGUIN. One strike against featureitis... - -This was probably a waste of a day or so. But what the hack -- rewriting the -strategy robot as an FSM was fun, and maybe the interface will set a good -example for the next guy. - -<*** FLAME ON ***> - -People who write curses games that require you to enter #@!!#$! coordinates -rather than doing the natural pick-and-place with cursor motions should be -stuffed in suits and condemned to write COBOL for the rest of their days... - -<*** FLAME OFF ***> - -O.K., I feel better now that I've got that off my chest... - -November 1993: I've added function key support, and ANSI/POSIXized the code. - -December 2012: This is ancient code now, mainly interesting as a -historical document of what primitive computer games looked like in -the 1980s - it dates from 1986, I rewrote it in 1989. The PNG icon in -the distribution is much later; thanks to Tor Gjerde who seems to have -built it for use with FVWM. - - Eric S. Raymond - [email protected] - (WWW: http://www.catb.org/~esr/) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/README.adoc new/bs-2.15/README.adoc --- old/bs-2.13/README.adoc 1970-01-01 01:00:00.000000000 +0100 +++ new/bs-2.15/README.adoc 2026-03-27 11:43:30.000000000 +0100 @@ -0,0 +1,39 @@ + BS 2.0 + +Battleships is an intrinsically silly game, but I couldn't resist fixing this +sucker. It now has a purely visual interface (you place ships and call for +shots by moving the cursor around the board using the standard yuhjklbn keys). + +The default game now disallows placement of ships so that they touch. A new +-c option is available to force the older behavior. + +I also removed the `seemiss' option (now always on) and `ask' (which is only +useful for cheating). And I ifdefed out the ditsy opening screen; if you want +it back, compile with -DPENGUIN. One strike against featureitis... + +This was probably a waste of a day or so. But what the hack -- rewriting the +strategy robot as an FSM was fun, and maybe the interface will set a good +example for the next guy. + +*** FLAME ON *** + +People who write curses games that require you to enter #@!!#$! coordinates +rather than doing the natural pick-and-place with cursor motions should be +stuffed in suits and condemned to write COBOL for the rest of their days... + +*** FLAME OFF *** + +O.K., I feel better now that I've got that off my chest... + +November 1993: I've added function key support, and ANSI/POSIXized the code. + +December 2012: This is ancient code now, mainly interesting as a +historical document of what primitive computer games looked like in +the 1980s - it dates from 1986, I rewrote it in 1989. The PNG icon in +the distribution is much later; thanks to Tor Gjerde who seems to have +built it for use with FVWM. + +This code is commonly packaged as "battleships". + +image:https://repology.org/badge/vertical-allrepos/battleships.svg[Repology +package status] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/bs.6 new/bs-2.15/bs.6 --- old/bs-2.13/bs.6 2024-02-13 19:06:06.000000000 +0100 +++ new/bs-2.15/bs.6 1970-01-01 01:00:00.000000000 +0100 @@ -1,95 +0,0 @@ -'\" t -.\" Title: bluemoon -.\" Author: [see the "AUTHOR(S)" section] -.\" Generator: Asciidoctor 2.0.16 -.\" Date: 2024-02-13 -.\" Manual: \ \& -.\" Source: \ \& -.\" Language: English -.\" -.TH "BS" "6" "2024-02-13" "\ \&" "\ \&" -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.ss \n[.ss] 0 -.nh -.ad l -.de URL -\fI\\$2\fP <\\$1>\\$3 -.. -.als MTO URL -.if \n[.g] \{\ -. mso www.tmac -. am URL -. ad l -. . -. am MTO -. ad l -. . -. LINKSTYLE blue R < > -.\} -.SH "NAME" -bs \- the Battleships game -.SH "SYNOPSIS" -.sp -\fBbs\fP [\-b | \-s ] [ \-c ] [\-v] -.SH "DESCRIPTION" -.sp -This program allows you to play the familiar Battleships game -against the computer on a 10x10 board. The interface is visual and -largely self\-explanatory; you place your ships and pick your shots by -moving the cursor around the board with the rogue/hack motion keys -hjklyubn. Your arrow keys will also work. -.sp -Note that when selecting a ship to place, you must type the -capital letter (these are, after all, capital ships). During ship -placement, the "r" command may be used to ignore the current position -and randomly place your currently selected ship. The "R" command will -place all remaining ships randomly. The ^L command (form feed, ASCII -12) will force a screen redraw). -.sp -The command\-line arguments control game modes. -.sp -\-b -.RS 4 -selects a `blitz\*(Aq variant -.RE -.sp -\-s -.RS 4 -selects a `salvo\*(Aq variant -.RE -.sp -\-c -.RS 4 -permits ships to be placed adjacently -.RE -.sp -\-v reports the program version -.sp -The "blitz" variant allows a side to shoot for as long as it continues to -score hits. -.sp -The "salvo" game allows a player one shot per turn for each of -his/her ships still afloat. This puts a premium scoring hits early -and knocking out some ships and also makes much harder the situation -where you face a superior force with only your PT\-boat. -.sp -Normally, ships must be separated by at least one square of open -water. The \-c option disables this check and allows them to -close\-pack. -.sp -The algorithm the computer uses once it has found a ship to sink -is provably optimal. The dispersion criterion for the random\-fire -algorithm may not be. -.SH "AUTHORS" -.sp -Originally written by one Bruce Holloway in 1986. Salvo mode added by -Chuck A. DeGaul (cbosgd!cad). Visual user interface, "closepack" -option, code rewrite and manual page by Eric S. Raymond -\c -.MTO "esr\(atsnark.thyrsus.com" "" "" -August 1989. Keypad support and ANSI/POSIX -conformance, November \*(Aq93. See \c -.URL "http://www.catb.org/~esr/" "" "" -for updates, -also other software and resources by ESR. \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/bs.adoc new/bs-2.15/bs.adoc --- old/bs-2.13/bs.adoc 2024-02-13 18:25:59.000000000 +0100 +++ new/bs-2.15/bs.adoc 2026-03-27 11:43:30.000000000 +0100 @@ -1,4 +1,5 @@ -= bluemoon(6) = +// spellcheck: add bs hjklyubn DeGaul cbosgd closepack POSIX += bs(6) = :doctype: manpage // SPDX-FileCopyrightText: (C) Eric S. Raymond <[email protected]> // SPDX-License-Identifier: BSD-2-Clause diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/bs.c new/bs-2.15/bs.c --- old/bs-2.13/bs.c 2024-02-13 19:21:24.000000000 +0100 +++ new/bs-2.15/bs.c 2026-03-27 11:43:30.000000000 +0100 @@ -11,6 +11,7 @@ #include <ctype.h> #include <curses.h> #include <signal.h> +#include <limits.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> @@ -82,7 +83,7 @@ static const char destroy[] = "Destroyer"; static const char ptboat[] = "PT Boat"; -static char name[40]; +static char name[LOGIN_NAME_MAX + 1]; static const char dftname[] = "stranger"; /* direction constants */ @@ -112,6 +113,7 @@ } ship_t; static bool checkplace(int b, ship_t *ss, int vis); +static void reset_ai_state(void); static ship_t plyship[SHIPTYPES] = { {carrier, 0, 'A', 5}, {battle, 0, 'B', 4}, {destroy, 0, 'D', 3}, @@ -124,8 +126,8 @@ }; /* "Hits" board, and main board. */ -static char hits[2][BWIDTH][BDEPTH]; -static char board[2][BWIDTH][BDEPTH]; +static char unsigned hits[2][BWIDTH][BDEPTH]; +static char unsigned board[2][BWIDTH][BDEPTH]; static int turn; /* 0=player, 1=computer */ static int plywon = 0, cpuwon = 0; /* How many games has each won? */ @@ -134,6 +136,26 @@ #define PR (void)addstr +/* computer AI state (reset each game) */ +#define S_MISS 0 +#define S_HIT 1 +#define S_SUNK -1 + +#define POSSIBLE(x, y) (ONBOARD(x, y) && !hits[COMPUTER][x][y]) +#define RANDOM_FIRE 0 +#define RANDOM_HIT 1 +#define HUNT_DIRECT 2 +#define FIRST_PASS 3 +#define REVERSE_JUMP 4 +#define SECOND_PASS 5 + +static int rf_turncount; +static int rf_srchstep = BEGINSTEP; +static int rf_huntoffs; +static int cpu_next = RANDOM_FIRE; +static bool cpu_used[4]; +static ship_t cpu_ts; + static void uninitgame(int sig GCC_UNUSED) /* end the game, either normally or due to signal */ { @@ -171,23 +193,24 @@ } static void intro(void) { - char *tmpname; + const char *tmpname; srand((unsigned)(time(0L) + getpid())); /* Kick the random number generator */ (void)signal(SIGINT, uninitgame); - (void)signal(SIGINT, uninitgame); + (void)signal(SIGHUP, uninitgame); + (void)signal(SIGTERM, uninitgame); (void)signal(SIGABRT, uninitgame); /* for assert(3) */ if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { (void)signal(SIGQUIT, uninitgame); } if ((tmpname = getlogin()) != 0) { - (void)strcpy(name, tmpname); - name[0] = toupper(name[0]); + (void)snprintf(name, sizeof(name), "%s", tmpname); + name[0] = toupper((unsigned char)name[0]); } else { - (void)strcpy(name, dftname); + (void)snprintf(name, sizeof(name), "%s", dftname); } (void)initscr(); @@ -238,6 +261,15 @@ #endif /* NCURSES_MOUSE_VERSION*/ } +static void reset_ai_state(void) { + rf_turncount = 0; + rf_srchstep = BEGINSTEP; + rf_huntoffs = 0; + cpu_next = RANDOM_FIRE; + memset(cpu_used, 0, sizeof(cpu_used)); + memset(&cpu_ts, 0, sizeof(cpu_ts)); +} + /* VARARGS1 */ static void prompt(int n, NCURSES_CONST char *f, const char *s) { /* print a message at the prompt line */ @@ -276,11 +308,18 @@ static void randomplace(int b, ship_t *ss) { /* generate a valid random ship placement into px,py */ - do { + int maxx, maxy; + ss->dir = rnd(2) ? E : S; - ss->x = rnd(BWIDTH - (ss->dir == E ? ss->length : 0)); - ss->y = rnd(BDEPTH - (ss->dir == S ? ss->length : 0)); + maxx = BWIDTH - (ss->dir == E ? ss->length : 0); + maxy = BDEPTH - (ss->dir == S ? ss->length : 0); + if (maxx < 0 || maxy < 0) { + error("Ship is too large for the board"); + exit(EXIT_FAILURE); + } + ss->x = rnd(maxx + 1); + ss->y = rnd(maxy + 1); } while (!checkplace(b, ss, false)); } @@ -293,8 +332,9 @@ (void)move(PROMPTLINE + 2, 0); announceopts(); - memset(board, 0, sizeof(char) * BWIDTH * BDEPTH * 2); - memset(hits, 0, sizeof(char) * BWIDTH * BDEPTH * 2); + memset(board, 0, sizeof(board)); + memset(hits, 0, sizeof(hits)); + reset_ai_state(); for (i = 0; i < SHIPTYPES; i++) { ss = cpuship + i; @@ -397,7 +437,10 @@ /* get a command letter */ prompt(1, "Type one of [%s] to pick a ship.", docked + 1); do { - c = toupper(getcoord(PLAYER)); + c = getcoord(PLAYER); + if (c >= 0 && c <= UCHAR_MAX) { + c = toupper((unsigned char)c); + } } while (!strchr(docked, c)); if (c == 'R') { @@ -417,7 +460,7 @@ do { c = getch(); - } while (!strchr("hjklrR", c) || c == FF); + } while (!strchr("hjklrR", c) && c != FF); if (c == FF) { (void)clearok(stdscr, true); @@ -594,12 +637,24 @@ case KEY_MOUSE: { MEVENT myevent; - getmouse(&myevent); + if (getmouse(&myevent) != OK) { + continue; + } if (atcpu && myevent.y >= CY(0) && - myevent.y <= CY(BDEPTH) && myevent.x >= CX(0) && - myevent.x <= CX(BDEPTH)) { + myevent.y <= CY(BDEPTH - 1) && myevent.x >= CX(0) && + myevent.x <= CX(BWIDTH - 1)) { curx = CXINV(myevent.x); cury = CYINV(myevent.y); + if (curx < 0) { + curx = 0; + } else if (curx >= BWIDTH) { + curx = BWIDTH - 1; + } + if (cury < 0) { + cury = 0; + } else if (cury >= BDEPTH) { + cury = BDEPTH - 1; + } return (' '); } else { beep(); @@ -653,7 +708,7 @@ return (collide); } -static bool checkplace(int b, ship_t *ss, int vis) { +static bool checkplace(int b, const ship_t *ss, int vis) { int l, xend, yend; /* first, check for board edges */ @@ -888,8 +943,8 @@ (void)refresh(); for (;;) { int ch = getch(); - if (islower(ch)) { - ch = toupper(ch); + if (ch >= 0 && ch <= UCHAR_MAX && islower((unsigned char)ch)) { + ch = toupper((unsigned char)ch); } if (ch == CTRLC) { uninitgame(0); @@ -908,15 +963,12 @@ static void randomfire(int *px, int *py) { /* random-fire routine -- implements simple diagonal-striping strategy */ - static int turncount = 0; - static int srchstep = BEGINSTEP; - static int huntoffs; /* Offset on search strategy */ int ypossible[BWIDTH * BDEPTH], xpossible[BWIDTH * BDEPTH], nposs; int ypreferred[BWIDTH * BDEPTH], xpreferred[BWIDTH * BDEPTH], npref; int x, y, i; - if (turncount++ == 0) { - huntoffs = rnd(srchstep); + if (rf_turncount++ == 0) { + rf_huntoffs = rnd(rf_srchstep); } /* first, list all possible moves */ @@ -927,8 +979,8 @@ xpossible[nposs] = x; ypossible[nposs] = y; nposs++; - if (((x + huntoffs) % srchstep) != - (y % srchstep)) { + if (((x + rf_huntoffs) % rf_srchstep) != + (y % rf_srchstep)) { xpreferred[npref] = x; ypreferred[npref] = y; npref++; @@ -948,8 +1000,8 @@ *px = xpossible[i]; *py = ypossible[i]; - if (srchstep > 1) { - --srchstep; + if (rf_srchstep > 1) { + --rf_srchstep; } } else { error("No moves possible?? Help!"); @@ -958,10 +1010,6 @@ } } -#define S_MISS 0 -#define S_HIT 1 -#define S_SUNK -1 - static int cpufire(int x, int y) { /* fire away at given location */ bool hit, sunk; @@ -991,7 +1039,10 @@ attrset(0); #endif /* A_COLOR */ - return ((hit ? (sunk ? S_SUNK : S_HIT) : S_MISS) ? true : false); + if (!hit) { + return S_MISS; + } + return sunk ? S_SUNK : S_HIT; } /* @@ -1000,117 +1051,111 @@ * between computer turns. */ static bool cputurn(void) { -#define POSSIBLE(x, y) (ONBOARD(x, y) && !hits[COMPUTER][x][y]) -#define RANDOM_FIRE 0 -#define RANDOM_HIT 1 -#define HUNT_DIRECT 2 -#define FIRST_PASS 3 -#define REVERSE_JUMP 4 -#define SECOND_PASS 5 - static int next = RANDOM_FIRE; - static bool used[4]; - static ship_t ts; int navail, x, y, d, n; int hit = S_MISS; - switch (next) { + switch (cpu_next) { case RANDOM_FIRE: /* last shot was random and missed */ refire: randomfire(&x, &y); if (!(hit = cpufire(x, y))) { - next = RANDOM_FIRE; + cpu_next = RANDOM_FIRE; } else { - ts.x = x; - ts.y = y; - ts.hits = 1; - next = (hit == S_SUNK) ? RANDOM_FIRE : RANDOM_HIT; + cpu_ts.x = x; + cpu_ts.y = y; + cpu_ts.hits = 1; + cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : RANDOM_HIT; } break; case RANDOM_HIT: /* last shot was random and hit */ - used[E / 2] = used[S / 2] = used[W / 2] = used[N / 2] = false; + cpu_used[E / 2] = cpu_used[S / 2] = cpu_used[W / 2] = + cpu_used[N / 2] = false; /* FALLTHROUGH */ case HUNT_DIRECT: /* last shot hit, we're looking for ship's long axis */ for (d = navail = 0; d < 4; d++) { - x = ts.x + xincr[d * 2]; - y = ts.y + yincr[d * 2]; - if (!used[d] && POSSIBLE(x, y)) { + x = cpu_ts.x + xincr[d * 2]; + y = cpu_ts.y + yincr[d * 2]; + if (!cpu_used[d] && POSSIBLE(x, y)) { navail++; } else { - used[d] = true; + cpu_used[d] = true; } } if (navail == 0) /* no valid places for shots adjacent... */ { goto refire; /* ...so we must random-fire */ } else { - for (d = 0, n = rnd(navail) + 1; n; n--) { - while (used[d]) { - d++; + for (d = 0, n = rnd(navail); d < 4; d++) { + if (cpu_used[d]) { + continue; + } + if (n-- == 0) { + break; } } - assert(d <= 4); + assert(d < 4); - used[d] = false; - x = ts.x + xincr[d * 2]; - y = ts.y + yincr[d * 2]; + cpu_used[d] = false; + x = cpu_ts.x + xincr[d * 2]; + y = cpu_ts.y + yincr[d * 2]; assert(POSSIBLE(x, y)); if (!(hit = cpufire(x, y))) { - next = HUNT_DIRECT; + cpu_next = HUNT_DIRECT; } else { - ts.x = x; - ts.y = y; - ts.dir = d * 2; - ts.hits++; - next = + cpu_ts.x = x; + cpu_ts.y = y; + cpu_ts.dir = d * 2; + cpu_ts.hits++; + cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS; } } break; case FIRST_PASS: /* we have a start and a direction now */ - x = ts.x + xincr[ts.dir]; - y = ts.y + yincr[ts.dir]; + x = cpu_ts.x + xincr[cpu_ts.dir]; + y = cpu_ts.y + yincr[cpu_ts.dir]; if (POSSIBLE(x, y) && (hit = cpufire(x, y))) { - ts.x = x; - ts.y = y; - ts.hits++; - next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS; + cpu_ts.x = x; + cpu_ts.y = y; + cpu_ts.hits++; + cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS; } else { - next = REVERSE_JUMP; + cpu_next = REVERSE_JUMP; } break; case REVERSE_JUMP: /* nail down the ship's other end */ - d = ts.dir + 4; - x = ts.x + ts.hits * xincr[d]; - y = ts.y + ts.hits * yincr[d]; + d = cpu_ts.dir + 4; + x = cpu_ts.x + cpu_ts.hits * xincr[d]; + y = cpu_ts.y + cpu_ts.hits * yincr[d]; if (POSSIBLE(x, y) && (hit = cpufire(x, y))) { - ts.x = x; - ts.y = y; - ts.dir = d; - ts.hits++; - next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS; + cpu_ts.x = x; + cpu_ts.y = y; + cpu_ts.dir = d; + cpu_ts.hits++; + cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS; } else { - next = RANDOM_FIRE; + cpu_next = RANDOM_FIRE; } break; case SECOND_PASS: /* kill squares not caught on first pass */ - x = ts.x + xincr[ts.dir]; - y = ts.y + yincr[ts.dir]; + x = cpu_ts.x + xincr[cpu_ts.dir]; + y = cpu_ts.y + yincr[cpu_ts.dir]; if (POSSIBLE(x, y) && (hit = cpufire(x, y))) { - ts.x = x; - ts.y = y; - ts.hits++; - next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS; + cpu_ts.x = x; + cpu_ts.y = y; + cpu_ts.hits++; + cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS; break; } else { - next = RANDOM_FIRE; + cpu_next = RANDOM_FIRE; } break; } @@ -1126,7 +1171,7 @@ #ifdef DEBUG (void)mvprintw(PROMPTLINE + 2, 0, "New state %d, x=%d, y=%d, d=%d", - next, x, y, d); + cpu_next, x, y, d); #endif /* DEBUG */ return ((hit) ? true : false); } @@ -1165,7 +1210,7 @@ return (sgetc("YN") == 'Y'); } -static void do_options(int c, char *op[]) { +static void do_options(int c, const char *op[]) { if (c > 1) { register int i; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bs-2.13/control new/bs-2.15/control --- old/bs-2.13/control 2024-02-01 17:47:40.000000000 +0100 +++ new/bs-2.15/control 2026-03-27 11:43:30.000000000 +0100 @@ -12,6 +12,8 @@ Homepage: http://www.catb.org/~esr/bs +XBS-Packaged-AsL battleships + XBS-HTML-Target: index.html XBS-Repository-URL: https://gitlab.com/esr/bs @@ -23,3 +25,5 @@ #XBS-Project-Tags: Games/Entertainment XBS-VC-Tag-Template: %(version)s + +XBS-Validate: make spellcheck ++++++ bs-fix-gcc15-errors.patch ++++++ Fix build with GCC 14+ (incompatible-pointer-types is an error): match the checkplace forward declaration to its const-qualified definition, and take plain char * in do_options (called with argv). Index: bs-2.15/bs.c =================================================================== --- bs-2.15.orig/bs.c +++ bs-2.15/bs.c @@ -112,7 +112,7 @@ bool placed; /* has it been placed on the board? */ } ship_t; -static bool checkplace(int b, ship_t *ss, int vis); +static bool checkplace(int b, const ship_t *ss, int vis); static void reset_ai_state(void); static ship_t plyship[SHIPTYPES] = { @@ -1210,7 +1210,7 @@ return (sgetc("YN") == 'Y'); } -static void do_options(int c, const char *op[]) { +static void do_options(int c, char *op[]) { if (c > 1) { register int i; ++++++ bs-fix-install-paths.patch ++++++ Fix install locations in the 2.15 Makefile: the binary was installed into MANDIR instead of BINDIR, and uninstall ignored DESTDIR. Index: bs-2.15/Makefile =================================================================== --- bs-2.15.orig/Makefile +++ bs-2.15/Makefile @@ -53,9 +53,9 @@ install: bs.6 uninstall install -m 0755 -d $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/ install -m 0755 -d $(DESTDIR)/usr/share/appdata - install -m 0755 bs $(DESTDIR)$(MANDIR)/ + install -m 0755 bs $(DESTDIR)$(BINDIR)/ install -m 0644 bs.6 $(DESTDIR)$(MANDIR)/man6/ install -m 0644 bs.desktop $(DESTDIR)/usr/share/applications/ install -m 0644 battleship.png $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/ install -m 0644 bs.adoc $(DESTDIR)/usr/share/appdata/ uninstall: - rm -f $(BINDIR)/bs /usr/share/man/man6/bs.6 + rm -f $(DESTDIR)$(BINDIR)/bs $(DESTDIR)/usr/share/man/man6/bs.6 # Export
