include ..\arwen\arwen.ew include ..\arwen\axtra.ew constant N = 5, -- columns M = 4, -- rows cLetter = Yellow, -- initial colour(!) cChosen = Purple, cPlayr2 = Purple, -- (2 player if!=c_Chosen) cHover = White, cLines = Black, cSelect = Black, -- (text/list of selected letters) cBackgnd = #EFF8FA, letters = shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ")[1..N*M] sequence fonts -- list of {width,handle}, see set_font() string chosen = "" constant main = create(Window, "honeycomb", 0, 0, 20, 20, 520, 540, 0), mainDC = getPrivateDC(main), viewDC = c_func(xCreateCompatibleDC, {NULL}), pSize = allocate_Point() integer ls, -- length of a single side dx, dy, -- bounding rectangle of a sloping side ox, oy, -- offsets needed to center things lw -- line width (10% of ls, tweaked) -- The total bounding rectange of a completed N by M honeycomb is N*(ls+dx)+dx by (2*M+1)*dy. -- However, as space for the chosen letters, pretend there is an extra row at the bottom. -- Use that to determine the best ls, and hence dx and dy, as the window is resized. constant cos60 = cos(2*PI*60/360), -- dx = ls*cos60 (cos60=0.5) sin60 = sin(2*PI*60/360) -- dy = ls*sin60 function font_info(integer size) atom hFont = createFontForDC(viewDC, "Calibri", size, Bold) {} = selectObject(viewDC,hFont) {} = c_func(xGetTextExtentPoint32,{viewDC,"W",1,pSize}) return {peek4u(pSize),hFont} end function fonts = {font_info(1)} procedure set_font(atom ls) while length(fonts)<=200 -- (arbitrary limit) and fonts[$][1]mxb) end if hy = floor((gy+remainder(hx,2))/2) end if return {hx,hy} end function integer dw = 0, dh = 0 -- client area width and height atom bmView integer vwX = 0, vwY = 0 -- actual size of the view bitmap function mainHandler(integer id, integer msg, atom wParam, object lParam) integer ch if msg=WM_SIZE then {{},{},dw,dh} = getClientRect(main) if dw>vwX or dh>vwY then -- we need a bigger bitmap bmView = c_func(xCreateCompatibleBitmap, {mainDC, dw, dh}) {} = deleteObject(selectObject(viewDC,bmView)) {vwX,vwY} = {dw,dh} end if -- width = N*(ls+dx)+dx = ls*(N*(1+cos60)+cos60), -- height = (2*M+3)*dy = ls*(2*M+3)*sin60, pick whichever fits: ls = min(floor((dw-10)/(N*(1+cos60)+cos60)), floor((dh-20)/((2*M+3)*sin60))) dx = floor(ls*cos60) -- (same as ls/2) dy = floor(ls*sin60) ox = floor((dw-((N*(ls+dx))+dx))/2) oy = floor((dh-((2*M+3)*dy))/2) lw = floor((ls-10)/10)+1 setPenWidth(lw) set_font(ls) elsif msg=WM_PAINT then setPenColor(cBackgnd) drawRectangleh(viewDC, True, 0, 0, dw, dh) for x=1 to N do for y=1 to M do drawHexagon(x,y) end for end for -- text/list of selected letters goes where (M+2)th row would: setPenColor(cSelect) wPuts2(viewDC,ox+dx+5,oy+(2*M+1)*dy+10,chosen) -- I needed this to get xy_to_hex() working: -- for i=1 to 400 do -- for j=1 to 400 do -- if xy_to_hex({i,j})={1,1} then -- drawRectangleh(viewDC, True, i, j, i+1, j+1) -- end if -- end for -- end for void = c_func(xBitBlt,{mainDC,0,0,dw,dh,viewDC,0,0,SRCCOPY}) elsif msg=WM_CHAR then if wParam=VK_ESCAPE then closeWindow(main) if id then end if -- suppress warnings -- elsif wParam='!' then -- ?9/0 else ch = upper(wParam) if find(ch,letters) and not find(ch,chosen) then chosen &= ch repaintWindow(main) end if end if elsif msg=WM_MOUSEMOVE then {mx,my} = xy_to_hex(lParam) repaintWindow(main) elsif msg = WM_LBUTTONDOWN then {mx,my} = xy_to_hex(lParam) if mx>=1 and mx<=N and my>=1 and my<=M then ch = letters[(my-1)*N+mx] if find(ch,letters) and not find(ch,chosen) then chosen &= ch repaintWindow(main) end if end if elsif msg=WM_GETMINMAXINFO then -- below this, things stop working... poke4(lParam+MINMAXINFO_ptMinTrackSize,{188,250}) end if return 0 end function setHandler(main,routine_id("mainHandler")) WinMain(main, SW_NORMAL)