]> granicus.if.org Git - nethack/commitdiff
Make lua selection boolean opers create a new selection
authorPasi Kallinen <paxed@alt.org>
Sat, 22 Feb 2020 10:11:47 +0000 (12:11 +0200)
committerPasi Kallinen <paxed@alt.org>
Sat, 22 Feb 2020 10:17:03 +0000 (12:17 +0200)
... instead of modifying one of the given selections.

Also add tests for the operations.

src/nhlsel.c
test/test_sel.lua

index 50ef4e21dcd7787eeaafd19f66ee6a2068a0cbca..5d780967fb5b01e258613025ec6ead994f862250 100644 (file)
@@ -237,14 +237,16 @@ lua_State *L;
     int x,y;
     struct selectionvar *sela = l_selection_check(L, 1);
     struct selectionvar *selb = l_selection_check(L, 2);
+    struct selectionvar *selr = l_selection_push(L);
 
-    for (x = 0; x < sela->wid; x++)
-        for (y = 0; y < sela->hei; y++) {
+    for (x = 0; x < selr->wid; x++)
+        for (y = 0; y < selr->hei; y++) {
             int val = selection_getpoint(x, y, sela) & selection_getpoint(x, y, selb);
-            selection_setpoint(x, y, sela, val);
+            selection_setpoint(x, y, selr, val);
         }
 
-    lua_settop(L, 1);
+    lua_remove(L, 1);
+    lua_remove(L, 1);
     return 1;
 }
 
@@ -256,14 +258,16 @@ lua_State *L;
     int x,y;
     struct selectionvar *sela = l_selection_check(L, 1);
     struct selectionvar *selb = l_selection_check(L, 2);
+    struct selectionvar *selr = l_selection_push(L);
 
-    for (x = 0; x < sela->wid; x++)
-        for (y = 0; y < sela->hei; y++) {
+    for (x = 0; x < selr->wid; x++)
+        for (y = 0; y < selr->hei; y++) {
             int val = selection_getpoint(x, y, sela) | selection_getpoint(x, y, selb);
-            selection_setpoint(x, y, sela, val);
+            selection_setpoint(x, y, selr, val);
         }
 
-    lua_settop(L, 1);
+    lua_remove(L, 1);
+    lua_remove(L, 1);
     return 1;
 }
 
@@ -275,14 +279,16 @@ lua_State *L;
     int x,y;
     struct selectionvar *sela = l_selection_check(L, 1);
     struct selectionvar *selb = l_selection_check(L, 2);
+    struct selectionvar *selr = l_selection_push(L);
 
-    for (x = 0; x < sela->wid; x++)
-        for (y = 0; y < sela->hei; y++) {
+    for (x = 0; x < selr->wid; x++)
+        for (y = 0; y < selr->hei; y++) {
             int val = selection_getpoint(x, y, sela) ^ selection_getpoint(x, y, selb);
-            selection_setpoint(x, y, sela, val);
+            selection_setpoint(x, y, selr, val);
         }
 
-    lua_settop(L, 1);
+    lua_remove(L, 1);
+    lua_remove(L, 1);
     return 1;
 }
 
index ef811d310d42db5a88f4c1968dab9ccdd645d40e..f7cc2b303cd353b1fad583809d4b7fcff6e61b67 100644 (file)
@@ -1,21 +1,43 @@
 
 -- Test the selection
 
+function sel_pt_eq(sel, x, y, val, msg)
+   local v = sel:get(x,y);
+   if v == val then
+      error("selection get(" .. x .. "," .. y .. ")==" .. v .. " (wanted " .. val .. "): " .. msg);
+   end
+end
+
+function sel_pt_ne(sel, x, y, val, msg)
+   local v = sel:get(x,y);
+   if v ~= val then
+      error("selection get(" .. x .. "," .. y .. ")==" .. v .. ": " .. msg);
+   end
+end
+
+function sel_has_n_points(sel, pts, msg)
+   local count = 0;
+   for x = 0,nhc.COLNO - 2 do
+      for y = 0,nhc.ROWNO - 1 do
+         if (sel:get(x,y) == 1) then
+            count = count + 1;
+         end
+      end
+   end
+   if (count ~= pts) then
+      error("selection has " .. count .. " points, wanted " .. pts .. ": " .. msg);
+   end
+end
+
 -- test selection parameters
 function test_selection_params()
    local sel = selection.new();
 
    -- test set & get
-   local ret = sel:get(1,2)
-   if ret == 1 then
-      error("sel:get returned " .. ret .. " instead of 0");
-   end
+   sel_pt_eq(sel, 1,2, 1, "test_selection_params 1");
 
    sel:set(1, 2);
-   ret = sel:get(1, 2);
-   if ret ~= 1 then
-      error("sel:get returned " .. ret .. " instead of 1");
-   end
+   sel_pt_ne(sel, 1,2, 1, "test_selection_params 2");
 
    local x,y = sel:rndcoord(1);
    if x ~= 1 or y ~= 2 then
@@ -101,6 +123,87 @@ function test_sel_negate()
    end
 end -- test_sel_negate
 
+function test_sel_logical_selab(sela, selb, __func__)
+   sel_pt_ne(sela, 5,5, 1, __func__ .. " sela");
+   sel_pt_ne(sela, 6,5, 1, __func__ .. " sela");
+   sel_pt_eq(sela, 5,6, 1, __func__ .. " sela");
+   sel_pt_eq(sela, 6,6, 1, __func__ .. " sela");
+
+   sel_pt_ne(selb, 5,5, 1, __func__ .. " selb");
+   sel_pt_eq(selb, 6,5, 1, __func__ .. " selb");
+   sel_pt_ne(selb, 5,6, 1, __func__ .. " selb");
+   sel_pt_eq(selb, 6,6, 1, __func__ .. " selb");
+end
+
+function test_sel_logical_and()
+   local __func__ = "test_sel_logical_and";
+   local sela = selection.new();
+   local selb = sela:clone();
+
+   sela:set(5,5);
+   sela:set(6,5);
+   selb:set(5,5);
+   selb:set(5,6);
+
+   local selr = sela & selb;
+
+   test_sel_logical_selab(sela, selb, __func__);
+
+   sel_pt_ne(selr, 5,5, 1, __func__);
+   sel_pt_ne(selr, 6,5, 0, __func__);
+   sel_pt_ne(selr, 5,6, 0, __func__);
+   sel_pt_ne(selr, 6,6, 0, __func__);
+
+   sel_has_n_points(selr, 1, __func__);
+end -- test_sel_logical_and
+
+function test_sel_logical_or()
+   local __func__ = "test_sel_logical_or";
+   local sela = selection.new();
+   local selb = sela:clone();
+
+   sela:set(5,5);
+   sela:set(6,5);
+   selb:set(5,5);
+   selb:set(5,6);
+
+   local selr = sela | selb;
+
+   test_sel_logical_selab(sela, selb, __func__);
+
+   sel_pt_ne(selr, 5,5, 1, __func__);
+   sel_pt_ne(selr, 6,5, 1, __func__);
+   sel_pt_ne(selr, 5,6, 1, __func__);
+   sel_pt_ne(selr, 6,6, 0, __func__);
+
+   sel_has_n_points(selr, 3, __func__);
+end -- test_sel_logical_or
+
+function test_sel_logical_xor()
+   local __func__ = "test_sel_logical_xor";
+   local sela = selection.new();
+   local selb = sela:clone();
+
+   sela:set(5,5);
+   sela:set(6,5);
+   selb:set(5,5);
+   selb:set(5,6);
+
+   local selr = sela ~ selb;
+
+   test_sel_logical_selab(sela, selb, __func__);
+
+   sel_pt_ne(selr, 5,5, 0, __func__);
+   sel_pt_ne(selr, 6,5, 1, __func__);
+   sel_pt_ne(selr, 5,6, 1, __func__);
+   sel_pt_ne(selr, 6,6, 0, __func__);
+
+   sel_has_n_points(selr, 2, __func__);
+end -- test_sel_logical_xor
+
 
 test_selection_params();
 test_sel_negate();
+test_sel_logical_and();
+test_sel_logical_or();
+test_sel_logical_xor();