tables unable to scroll manually or using table.scroll_to_bottom
- Dominant language
- Python
- Stars
- 5.4k
- Forks
- 829
- Avg merge
- 15h 39m
- Merged PRs (30d)
- 40
Description
### Describe the bug
here are the simplified codes of my application, which only the number inputs for 'total attacker' and 'total defender', and the button 'allout attack' is working and there is no logical calculations:
use for syntax, logic check, complete code down below
```
from os import device_encoding
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
import random
class RISKdicer(toga.App):
def startup(self):
main_box = toga.Box(style=Pack(direction=COLUMN,padding=5))
main_UI = toga.ScrollContainer(content = main_box)
numbers_box = toga.Box(style=Pack(direction=ROW))
buttons_box = toga.Box(style=Pack(direction=ROW))
display_box = toga.Box(style=Pack(direction=COLUMN))
atker_box = toga.Box(style=Pack(direction=COLUMN))
defer_box = toga.Box(style=Pack(direction=COLUMN,padding_left=5))
atkernum_container = toga.Box(style=Pack(direction=ROW))
defernum_container = toga.Box(style=Pack(direction=ROW))
atkernums_box = toga.Box(style=Pack(direction=COLUMN))
defernums_box = toga.Box(style=Pack(direction=COLUMN))
atkerinput_box = toga.Box(style=Pack(direction=COLUMN))
deferinput_box = toga.Box(style=Pack(direction=COLUMN))
atkernum_label = toga.Label('Total number of Attacker (exclude artillery): ',style=Pack(padding_top=3))
self.atkernum_input = toga.NumberInput(step=1,min=2,value=2,style=Pack(height=30))
defernum_label = toga.Label('Total number of Defender (include artillery): ',style=Pack(padding_top=3))
self.defernum_input = toga.NumberInput(step=1,min=1,value=1,style=Pack(height=30))
chaos_button = toga.Button('Allout attack',on_press=self.confirm_auto,style=Pack(height=30))
self.nums_table = toga.Table(headings=[
'round','attacker','atk Cavalry','atk Artillery','Commander','defender','def Artillery','landing'],style=Pack(flex=1,height=70,width=720))
self.dice_table = toga.Table(headings=[
'round','dice A1','dice A2','dice A3','dice D1','dice D2','dice D3'],style=Pack(flex=1,height=100,width=720))
clear_table_button = toga.Button('Clear table',on_press=self.clear_table)
atkernums_box.add(atkernum_label)
defernums_box.add(defernum_label)
atkerinput_box.add(self.atkernum_input)
deferinput_box.add(self.defernum_input)
atkernum_container.add(atkernums_box)
atkernum_container.add(atkerinput_box)
defernum_container.add(defernums_box)
defernum_container.add(deferinput_box)
atker_box.add(atkernum_container)
defer_box.add(defernum_container)
boolean_box.add(self.atkerhasC_switch)
boolean_box.add(self.landing_switch)
CA_box.add(CA_label_button_box)
CA_box.add(CA_atker_input_box)
CA_box.add(CA_defer_input_box)
numbers_box.add(atker_box)
numbers_box.add(defer_box)
buttons_box.add(chaos_button)
buttons_box.add(throw_dice_button)
buttons_box.add(CA_box)
display_box.add(self.nums_table)
display_box.add(self.dice_table)
display_box.add(clear_table_button)
main_box.add(numbers_box)
main_box.add(atkerCnum_box)
main_box.add(boolean_box)
main_box.add(buttons_box)
main_box.add(display_box)
self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = main_UI
self.main_window.show()
if toga.platform.current_platform == 'android':
self._impl.native.getSupportActionBar().hide()
def clear_table(self,widget):
self.nums_table.data = 0
self.dice_table.data = 0
def confirm_auto(self,widget):
atkernum_display = self.atkernum_input.value
atkerC_display = self.atkerCnum_input.value
atkerA_display = self.atkerAnum_input.value
defernum_display = self.defernum_input.value
deferA_display = self.deferAnum_input.value
self.CA_atker_input.value
self.CA_defer_input.value
boolean_atkerhasC_display = self.atkerhasC_switch.value
boolean_landing_display = self.landing_switch.value
self.nums_table.data.append(('',atkernum_display,atkerC_display,atkerA_display,boolean_atkerhasC_display,defernum_display,deferA_display,boolean_landing_display))
self.nums_table.scroll_to_bottom()
self.main_window.confirm_dialog('Confirmation','Do you really want to do this?',on_result=self.allout_attack)
def allout_attack(self,widget,result):
if result == True:
roundnum = 0
atkernum = self.atkernum_input.value
defernum = self.defernum_input.value
while atkernum > 1 and defernum > 0:
roundnum += 1
if atkernum > 3:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
elif atkernum > 2:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = 0
diceA3 = 0
if defernum > 1:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
diceD1 = random.randint(1,6)
diceD2 = 0
diceD3 = 0
if diceA1 > diceD1:
defernum -= 1
else:
atkernum -= 1
if diceA2 > 0 and diceD2 > 0:
if diceA2 > diceD2:
defernum -= 1
else:
atkernum -= 1
if diceA3 > 0 and diceD3 > 0:
if diceA3 > diceD3:
defernum -= 1
else:
atkernum -= 1
self.dice_table.data.append((roundnum,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.nums_table.data.append((roundnum,atkernum,atkerCnum,'atkerA','',defernum,'deferA'))
self.nums_table.scroll_to_bottom()
self.nums_table.data.append('')
self.dice_table.scroll_to_bottom()
self.dice_table.data.append('')
else:
None
```
here are the complete codes of my application:
use this to compile into apk and test
```
from os import device_encoding
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
import random
class RISKdicer(toga.App):
def startup(self):
main_box = toga.Box(style=Pack(direction=COLUMN,padding=5))
main_UI = toga.ScrollContainer(content = main_box)
numbers_box = toga.Box(style=Pack(direction=ROW))
boolean_box = toga.Box(style=Pack(direction=ROW))
buttons_box = toga.Box(style=Pack(direction=ROW))
display_box = toga.Box(style=Pack(direction=COLUMN))
atker_box = toga.Box(style=Pack(direction=COLUMN))
atker_label = toga.Label('Attacker')
defer_box = toga.Box(style=Pack(direction=COLUMN,padding_left=5))
defer_label = toga.Label('Defender')
atkernum_container = toga.Box(style=Pack(direction=ROW))
defernum_container = toga.Box(style=Pack(direction=ROW))
atkernums_box = toga.Box(style=Pack(direction=COLUMN))
defernums_box = toga.Box(style=Pack(direction=COLUMN))
atkerinput_box = toga.Box(style=Pack(direction=COLUMN))
deferinput_box = toga.Box(style=Pack(direction=COLUMN))
atkerCnum_box = toga.Box(style=Pack(direction=ROW))
CA_box = toga.Box(style=Pack(direction=COLUMN))
CA_label_button_box = toga.Box(style=Pack(direction=ROW))
CA_atker_input_box = toga.Box(style=Pack(direction=ROW))
CA_defer_input_box = toga.Box(style=Pack(direction=ROW))
atkernum_label = toga.Label('Total number of Attacker (exclude artillery): ',style=Pack(padding_top=3))
self.atkernum_input = toga.NumberInput(step=1,min=2,value=2,style=Pack(height=30))
defernum_label = toga.Label('Total number of Defender (include artillery): ',style=Pack(padding_top=3))
self.defernum_input = toga.NumberInput(step=1,min=1,value=1,style=Pack(height=30))
self.atkerhasC_switch = toga.Switch('Attacker has Commander',value=False)
atkerAnum_label = toga.Label('Number of Attacker Artillery: ',style=Pack(padding_top=9))
self.atkerAnum_input = toga.NumberInput(step=1,min=0,value=0,style=Pack(height=30))
deferAnum_label = toga.Label('Number of Defender Artillery: ',style=Pack(padding_top=9))
self.deferAnum_input = toga.NumberInput(step=1,min=0,value=0,style=Pack(height=30))
atkerCnum_label = toga.Label('Number of Attacker Cavalry in adjacent territories to target: ',style=Pack(padding_top=3))
self.atkerCnum_input = toga.NumberInput(step=1,min=0,value=0,style=Pack(height=30))
self.landing_switch = toga.Switch('Amphibious attack',value=False)
chaos_button = toga.Button('Allout attack',on_press=self.confirm_auto,style=Pack(height=30))
throw_dice_button = toga.Button('Throw dice once',on_press=self.confirm_manual,style=Pack(height=30))
CA_label = toga.Label('Conditional skirmish',style=Pack(padding_top=5))
CA_atker_label = toga.Label('Halt attack when less than or X attackers (including cavalry) left: ',style=Pack(padding_top=3))
self.CA_atker_input = toga.NumberInput(step=1,min=1,value=1)
CA_defer_label = toga.Label('Retreat when less than or X defenders left: ',style=Pack(padding_top=3))
self.CA_defer_input = toga.NumberInput(step=1,min=0,value=0)
CA_button = toga.Button('Quick attack',on_press=self.confirm_conditional,style=Pack(height=30))
self.nums_table = toga.Table(headings=[
'round','attacker','atk Cavalry','atk Artillery','Commander','defender','def Artillery','landing'],style=Pack(flex=1,height=70,width=720))
self.dice_table = toga.Table(headings=[
'round','dice A1','dice A2','dice A3','dice D1','dice D2','dice D3'],style=Pack(flex=1,height=100,width=720))
clear_table_button = toga.Button('Clear table',on_press=self.clear_table)
atkernums_box.add(atkernum_label)
atkernums_box.add(atkerAnum_label)
defernums_box.add(defernum_label)
defernums_box.add(deferAnum_label)
atkerinput_box.add(self.atkernum_input)
atkerinput_box.add(self.atkerAnum_input)
deferinput_box.add(self.defernum_input)
deferinput_box.add(self.deferAnum_input)
atkerCnum_box.add(atkerCnum_label)
atkerCnum_box.add(self.atkerCnum_input)
CA_label_button_box.add(CA_label)
CA_label_button_box.add(CA_button)
CA_atker_input_box.add(CA_atker_label)
CA_atker_input_box.add(self.CA_atker_input)
CA_defer_input_box.add(CA_defer_label)
CA_defer_input_box.add(self.CA_defer_input)
atkernum_container.add(atkernums_box)
atkernum_container.add(atkerinput_box)
defernum_container.add(defernums_box)
defernum_container.add(deferinput_box)
atker_box.add(atker_label)
atker_box.add(atkernum_container)
defer_box.add(defer_label)
defer_box.add(defernum_container)
boolean_box.add(self.atkerhasC_switch)
boolean_box.add(self.landing_switch)
CA_box.add(CA_label_button_box)
CA_box.add(CA_atker_input_box)
CA_box.add(CA_defer_input_box)
numbers_box.add(atker_box)
numbers_box.add(defer_box)
buttons_box.add(chaos_button)
buttons_box.add(throw_dice_button)
buttons_box.add(CA_box)
display_box.add(self.nums_table)
display_box.add(self.dice_table)
display_box.add(clear_table_button)
main_box.add(numbers_box)
main_box.add(atkerCnum_box)
main_box.add(boolean_box)
main_box.add(buttons_box)
main_box.add(display_box)
self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = main_UI
self.main_window.show()
if toga.platform.current_platform == 'android':
self._impl.native.getSupportActionBar().hide()
def clear_table(self,widget):
self.nums_table.data = 0
self.dice_table.data = 0
def confirm_auto(self,widget):
atkernum_display = self.atkernum_input.value
atkerC_display = self.atkerCnum_input.value
atkerA_display = self.atkerAnum_input.value
defernum_display = self.defernum_input.value
deferA_display = self.deferAnum_input.value
self.CA_atker_input.value
self.CA_defer_input.value
boolean_atkerhasC_display = self.atkerhasC_switch.value
boolean_landing_display = self.landing_switch.value
self.nums_table.data.append(('',atkernum_display,atkerC_display,atkerA_display,boolean_atkerhasC_display,defernum_display,deferA_display,boolean_landing_display))
self.nums_table.scroll_to_bottom()
self.main_window.confirm_dialog('Confirmation','Do you really want to do this?',on_result=self.allout_attack)
def confirm_manual(self,widget):
self.atkernum_store = self.atkernum_input.value
self.atkerC_store = self.atkerCnum_input.value
self.atkerA_store = self.atkerAnum_input.value
self.defernum_store = self.defernum_input.value
self.deferA_store = self.deferAnum_input.value
boolean_atkerhasC_display = self.atkerhasC_switch.value
boolean_landing_display = self.landing_switch.value
self.roundnum_store = 0
self.nums_table.data.append(('',self.atkernum_store,self.atkerC_store,self.atkerA_store,boolean_atkerhasC_display,self.defernum_store,self.deferA_store,boolean_landing_display))
self.nums_table.scroll_to_bottom()
self.main_window.confirm_dialog('Confirmation','Do you really want to do this?',on_result=self.dice_once)
def confirm_conditional(self,widget):
atkernum_display = self.atkernum_input.value
atkerC_display = self.atkerCnum_input.value
atkerA_display = self.atkerAnum_input.value
defernum_display = self.defernum_input.value
deferA_display = self.deferAnum_input.value
self.CA_atker_input.value
self.CA_defer_input.value
boolean_atkerhasC_display = self.atkerhasC_switch.value
boolean_landing_display = self.landing_switch.value
self.nums_table.data.append(('',atkernum_display,atkerC_display,atkerA_display,boolean_atkerhasC_display,defernum_display,deferA_display,boolean_landing_display))
self.nums_table.scroll_to_bottom()
self.main_window.confirm_dialog('Confirmation','Do you really want to do this?',on_result=self.conditional_attack)
def allout_attack(self,widget,result):
if result == True:
roundnum = 0
atkernum = self.atkernum_input.value
atkerCnum = self.atkerCnum_input.value
atkerAnum = self.atkerAnum_input.value
defernum = self.defernum_input.value
deferAnum = self.deferAnum_input.value
boolean_atkerhasC = self.atkerhasC_switch.value
boolean_landing = self.landing_switch.value
while atkernum + atkerCnum > 1 and defernum > 0:
roundnum += 1
if atkernum + atkerCnum > 3:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
else:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
elif atkernum + atkerCnum > 2:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = random.randint(1,6)
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = 0
else:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = 0
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = 0
diceA3 = 0
if defernum > 1:
if boolean_landing == True:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = random.randint(1,6)
else:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
if boolean_landing == True:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
diceD1 = random.randint(1,6)
diceD2 = 0
diceD3 = 0
if diceA1 < diceA2:
m = diceA1
diceA1 = diceA2
diceA2 = m
if diceA2 < diceA3:
m = diceA2
diceA2 = diceA3
diceA3 = m
if diceA1 < diceA2:
m = diceA1
diceA1 = diceA2
diceA2 = m
if diceD1 < diceD2:
m = diceD1
diceD1 = diceD2
diceD2 = m
if diceD2 < diceD3:
m = diceD2
diceD2 = diceD3
diceD3 = m
if diceD1 < diceD2:
m = diceD1
diceD1 = diceD2
diceD2 = m
if atkerAnum > 0 or deferAnum > 0:
self.dice_table.data.append((roundnum,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.dice_table.scroll_to_bottom()
if atkerAnum > 2:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
if diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
elif atkerAnum > 1:
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
elif diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
else:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
elif atkerAnum > 0:
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
elif diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
else:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
if deferAnum > 2:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
if diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
if diceA3 > 0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
elif deferAnum > 1:
if diceA3 > 0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
if diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
elif diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
else:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
elif deferAnum > 0:
if diceA3 >0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
elif diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
else:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
if diceA1 > diceD1:
defernum -= 1
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if diceA2 > 0 and diceD2 > 0:
if diceA2 > diceD2:
defernum -= 1
if defernum < 0:
defernum = 0
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if diceA3 > 0 and diceD3 > 0:
if diceA3 > diceD3:
defernum -= 1
if defernum < 0:
defernum = 0
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if deferAnum > defernum:
deferAnum = defernum
self.dice_table.data.append((roundnum,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.nums_table.data.append((roundnum,atkernum,atkerCnum,'atkerA','',defernum,'deferA'))
self.nums_table.scroll_to_bottom()
self.nums_table.data.append('')
self.dice_table.scroll_to_bottom()
self.dice_table.data.append('')
if defernum < 1:
self.main_window.info_dialog('Result',f'Attack success, remaining attacker: {atkernum}, remaining cavalry: {atkerCnum}')
elif atkernum < 2:
self.main_window.info_dialog('Result',f'Attack failed, remaining defender: {defernum}')
else:
None
def conditional_attack(self,widget,result):
if result == True:
roundnum = 0
atkernum = self.atkernum_input.value
atkerCnum = self.atkerCnum_input.value
atkerAnum = self.atkerAnum_input.value
defernum = self.defernum_input.value
deferAnum = self.deferAnum_input.value
boolean_atkerhasC = self.atkerhasC_switch.value
boolean_landing = self.landing_switch.value
while atkernum + atkerCnum > self.CA_atker_input.value and defernum > self.CA_defer_input.value:
roundnum += 1
if atkernum + atkerCnum > 3:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
else:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
elif atkernum + atkerCnum > 2:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = random.randint(1,6)
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = 0
else:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = 0
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = 0
diceA3 = 0
if defernum > 1:
if boolean_landing == True:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = random.randint(1,6)
else:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
if boolean_landing == True:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
diceD1 = random.randint(1,6)
diceD2 = 0
diceD3 = 0
if diceA1 < diceA2:
m = diceA1
diceA1 = diceA2
diceA2 = m
if diceA2 < diceA3:
m = diceA2
diceA2 = diceA3
diceA3 = m
if diceA1 < diceA2:
m = diceA1
diceA1 = diceA2
diceA2 = m
if diceD1 < diceD2:
m = diceD1
diceD1 = diceD2
diceD2 = m
if diceD2 < diceD3:
m = diceD2
diceD2 = diceD3
diceD3 = m
if diceD1 < diceD2:
m = diceD1
diceD1 = diceD2
diceD2 = m
if atkerAnum > 0 or deferAnum > 0:
self.dice_table.data.append((roundnum,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.dice_table.scroll_to_bottom()
if atkerAnum > 2:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
if diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
elif atkerAnum > 1:
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
elif diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
else:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
elif atkerAnum > 0:
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
elif diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
else:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
if deferAnum > 2:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
if diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
if diceA3 > 0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
elif deferAnum > 1:
if diceA3 > 0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
if diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
elif diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
else:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
elif deferAnum > 0:
if diceA3 >0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
elif diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
else:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
if diceA1 > diceD1:
defernum -= 1
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if diceA2 > 0 and diceD2 > 0:
if diceA2 > diceD2:
defernum -= 1
if defernum < 0:
defernum = 0
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if diceA3 > 0 and diceD3 > 0:
if diceA3 > diceD3:
defernum -= 1
if defernum < 0:
defernum = 0
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if deferAnum > defernum:
deferAnum = defernum
self.dice_table.data.append((roundnum,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.nums_table.data.append((roundnum,atkernum,atkerCnum,'atkerA','',defernum,'deferA'))
self.nums_table.scroll_to_bottom()
self.nums_table.data.append('')
self.dice_table.scroll_to_bottom()
self.dice_table.data.append('')
if defernum <= self.CA_defer_input.value:
self.main_window.info_dialog('Result',f'Attack success, remaining attacker: {atkernum}, remaining cavalry: {atkerCnum}, retreated defender: {defernum}')
elif atkernum + atkerCnum <= self.CA_atker_input.value:
self.main_window.info_dialog('Result',f'Attack failed, remaining attacker: {atkernum}, remaining cavalry: {atkerCnum}, remaining defender: {defernum}')
else:
None
def dice_once(self, widget, result):
if result == True:
self.roundnum_store += 1
atkernum = self.atkernum_store
defernum = self.defernum_store
atkerCnum = self.atkerC_store
atkerAnum = self.atkerA_store
deferAnum = self.deferA_store
boolean_atkerhasC = self.atkerhasC_switch.value
boolean_landing = self.landing_switch.value
if atkernum + atkerCnum > 1 and defernum > 0:
if atkernum + atkerCnum > 3:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
else:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = random.randint(1,6)
elif atkernum + atkerCnum > 2:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = random.randint(1,6)
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = random.randint(1,6)
diceA3 = 0
else:
if boolean_atkerhasC == True:
diceA1 = 6
diceA2 = 0
diceA3 = 0
else:
diceA1 = random.randint(1,6)
diceA2 = 0
diceA3 = 0
if defernum > 1:
if boolean_landing == True:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = random.randint(1,6)
else:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
if boolean_landing == True:
diceD1 = random.randint(1,6)
diceD2 = random.randint(1,6)
diceD3 = 0
else:
diceD1 = random.randint(1,6)
diceD2 = 0
diceD3 = 0
if diceA1 < diceA2:
m = diceA1
diceA1 = diceA2
diceA2 = m
if diceA2 < diceA3:
m = diceA2
diceA2 = diceA3
diceA3 = m
if diceA1 < diceA2:
m = diceA1
diceA1 = diceA2
diceA2 = m
if diceD1 < diceD2:
m = diceD1
diceD1 = diceD2
diceD2 = m
if diceD2 < diceD3:
m = diceD2
diceD2 = diceD3
diceD3 = m
if diceD1 < diceD2:
m = diceD1
diceD1 = diceD2
diceD2 = m
if atkerAnum > 0 or deferAnum > 0:
self.dice_table.data.append((self.roundnum_store,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.dice_table.scroll_to_bottom()
if atkerAnum > 2:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
if diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
elif atkerAnum > 1:
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
elif diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
else:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
elif atkerAnum > 0:
if diceD3 > 0:
diceD3 -= 1
if diceD3 == 0:
diceD3 = 1
elif diceD2 > 0:
diceD2 -= 1
if diceD2 == 0:
diceD2 = 1
else:
diceD1 -= 1
if diceD1 == 0:
diceD1 = 1
if deferAnum > 2:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
if diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
if diceA3 > 0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
elif deferAnum > 1:
if diceA3 > 0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
if diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
elif diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
else:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
elif deferAnum > 0:
if diceA3 >0:
diceA3 -= 1
if diceA3 == 0:
diceA3 = 1
elif diceA2 > 0:
diceA2 -= 1
if diceA2 == 0:
diceA2 = 1
else:
diceA1 -= 1
if diceA1 == 0:
diceA1 = 1
if diceA1 > diceD1:
defernum -= 1
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if diceA2 > 0 and diceD2 > 0:
if diceA2 > diceD2:
defernum -= 1
if defernum < 0:
defernum = 0
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if diceA3 > 0 and diceD3 > 0:
if diceA3 > diceD3:
defernum -= 1
if defernum < 0:
defernum = 0
else:
atkernum -= 1
if atkernum < 1:
atkernum = 1
atkerCnum -= 1
if deferAnum > defernum:
deferAnum = defernum
self.dice_table.data.append((self.roundnum_store,diceA1,diceA2,diceA3,diceD1,diceD2,diceD3))
self.nums_table.data.append((self.roundnum_store,atkernum,atkerCnum,atkerAnum,'',defernum,deferAnum))
self.nums_table.scroll_to_bottom()
self.dice_table.scroll_to_bottom()
self.atkernum_store = atkernum
self.atkerC_store = atkerCnum
self.defernum_store = defernum
self.deferA_store = deferAnum
self.main_window.info_dialog('Result',f'Remaining attacker: {atkernum}, remaining cavalry: {atkerCnum}, remaining defender: {defernum}',on_result=self.confirm_continue)
else:
self.nums_table.data.append('')
self.dice_table.data.append('')
self.main_window.info_dialog('Error','Cannot start attack, check attacker/ defender numbers.')
else:
None
def confirm_continue(self,widget,result):
if self.atkernum_store + self.atkerC_store < 2:
self.main_window.info_dialog('Result',f'Attack failed, remaining defender: {self.defernum_store}, remaining D.artillery: {self.deferA_store}')
elif self.defernum_store < 1:
self.main_window.info_dialog('Result',f'Attack success, remaining attacker: {self.atkernum_store}, remaining cavalry: {self.atkerC_store}')
else:
self.main_window.confirm_dialog('Continue?','Do you wish to continue?',on_result=self.dice_once)
def main():
return RISKdicer()
```
### Steps to reproduce
1. briefcase create android, briefcase build android
2. download and run app on an android device
3. input numbers larger than 10 for both 'attacker' and 'defender'
4. click 'allout attack' button
5. confirm the dialog
6. the table should automatically generate lines and scroll to bottom after the while loops
7. try to scroll the table
8. See error
### Expected behavior
expectation:
the tables should automatically scroll to bottom when the function is complete
observation:
in briefcase dev - table can and does scroll to bottom
on android phone - table does not scroll at all
### Screenshots

^screenshot of briefcase dev using complete code, there is a slider for the table and it did automatically scroll to bottom

^screenshot of android phone running the app, the table is un-scrollable and does not automatically scroll, both screenshot shows the same code running
### Environment
- Operating System: android
- Python version: 3.11
- Software versions:
- Briefcase:
- Toga: 0.4.0
- ...
### Logs
```
```
### Additional context
_No response_
Contributor guide
Research direction
Reproduce the reported behavior in the supplied Android APK example, focusing on toga.Table, toga.ScrollContainer, manual scrolling, and scroll_to_bottom(). Start by checking how these widgets handle scrolling on Android; done means both tables scroll manually and scroll_to_bottom() reaches the final row without breaking the application.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, python
- Domain
- frontend, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100