A frontend web challenge

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
NsAI70G.mp4


Lets have a web challenge ? This challenge do not need any server side engine.
Just a static local webpage file that you can load using any browser will too. For consistency sake,
we will stick with Google Chrome so that we have a consistent web environment.

PROBLEM
Without resorting to Javascript, or any other possible client side programming languages (just to have a complete coverage), design a simple webpage that will exhibit the behaviour when the user interact with the interface as shown in the short video above.

Please kindly share your webpage source code within SPOILERS to demonstrate your approach.

:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Lets put up PART 2 now. Once you are done with PART 1, you can go ahead and try PART 2.
Same requirement no Javascript.
The example range may shows from -20 to 20, but it is just a simple change to go from -1000 to 1000
TNG87WH.mp4


Have fun
:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Woooo... no javascript also a hard problem ?

No web developers lurking in HWZ ?
Frontend with javascript only left 2 possibilities.
HTML + CSS.

:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Yup, now can, interesting, button onclick flip the text. I'll give it a try
Don't assume anything you see. In the web world, looks can be deceiving.
Read what you need to do, what are the constraints, don't over think.

:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Well... not sure if there is anyone solved PART 1 yet ? If so, here is PART 3
Same "No Javascript" constraint applies
OlvJdwZ.gif


:)
 
Last edited:

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Maybe next time I should set a challenge that generate a complex webpage without any written HTML source codes, just with Javascript contain within one single <script> tag.

:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Here is the code to PART 1.
HTML:
<html>
<head>
  <meta charset="utf-8">
  <style>
  a {
      display: inline-block;
      width: 100px;
      height: 20px;
      background: blue;
      padding: 5px;
      text-align: center;
      border-radius: 10px;
      color: white;
      font-weight: bold;
      text-decoration: none;
      line-height: 20px;
      margin: 3px;
  }

  .flip {
    transform: rotate(180deg);
  }

  #content {
    width: fit-content;
  }

  #content :nth-child(even)  {
    display: none
  }

  #content :nth-child(odd)  {
    display: block
  }

  #content:target :nth-child(even)  {
    display: block
  }

  #content:target :nth-child(odd)  {
    display: none
  }
  </style>
<head>
</head>
<body>
  <div id="content">
    <p>The quick brown fox jumps over the lazy dog</p>
    <!-- <p>ƃop ʎzɐl ǝɥʇ ɹǝʌo sdɯnɾ xoɟ uʍoɹq ʞɔınᕹ ǝɥʇ</p> -->
    <p class="flip">The quick brown fox jumps over the lazy dog</p>
  </div>
  <a href="#content">FLIP IT</a>
  <a href="#">REVERT</a>
</body>
</html>

This should give you a glimpse to what is the general concept, but it wouldn't solve PART 2 and 3 easily. PART 2 is simpler, I would say dimensional problem. PART 3 will require more than just knowing how to code frontend codes, you need to know how to code codes (nope this is not a typo).

:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
There is PART 2
PHP:
<?php
$MAX       = 100;
$MIN       = -1 * $MAX;
?>
<html>
<head>
  <title>Web Challenge 2</title>
  <style>
  a {
      display: inline-block;
      width: 100px;
      height: 20px;
      background: blue;
      padding: 5px;
      text-align: center;
      border-radius: 10px;
      color: white;
      font-weight: bold;
      text-decoration: none;
      line-height: 20px;
      margin: 3px;
  }
  div.alternate > div {
    position: relative;
    text-align: center;
    flex-direction: column;
  }

  div.main > div {
    display: none;
    text-align: center;
    flex-direction: column;
  }

  body > div {
width: 100%;
    text-align: center;
  }

  body > div > div {
    background-color: white;
    position: absolute;
  }

  body > div > div > div > p {
    font-size: 40pt;
  }

<?php
  for ($i = $MIN; $i <= $MAX; $i++) {
?>
  #n<?=$i?>:target,
<?php
  }
?>
  doesnothing
  { display: flex }
  </style>
</head>
<body>
<div>
  <div class="alternate">
    <div>
      <p>0</p>
      <div>
        <a href="#n-1">-1</a>
        <a href="#n1">+1</a>
      </div>
    </div>
  </div>
  <div class="main">
  <?php
    for ($i = $MIN; $i <= $MAX; $i++) {
      $prevlabel = $i > $MIN ? "-1" : "END";
      $prev      = $i > $MIN ? "#n".($i-1) : "#n$i";
      $nextlabel = $i < $MAX ? "+1" : "END";
      $next      = $i < $MAX ? "#n".($i+1) : "#n$i";
  ?>
    <div id="n<?=$i?>">
      <p><?=$i?></p>
      <div>
        <a href="<?=$prev?>"><?=$prevlabel?></a>
        <a href="<?=$next?>"><?=$nextlabel?></a>
      </div>
    </div>
  <?php
    }
  ?>
  </div>
</div>
</body>
</html>

Before you jump into the conclusion thinking, hey why use php script engine ? Same as Javascript what, only backend!
That's why I will show you the following
Code:
$ php part2.php > part2.html

I'm a software engineer, nothing wrong with engaging a tool to help me code, but it's just a static webpage with no Javascript and still exhibit the dynamism it requires.
HTML:
<html>
<head>
  <title>Web Challenge 2</title>
  <style>
  a {
      display: inline-block;
      width: 100px;
      height: 20px;
      background: blue;
      padding: 5px;
      text-align: center;
      border-radius: 10px;
      color: white;
      font-weight: bold;
      text-decoration: none;
      line-height: 20px;
      margin: 3px;
  }
  div.alternate > div {
    position: relative;
    text-align: center;
    flex-direction: column;
  }

  div.main > div {
    display: none;
    text-align: center;
    flex-direction: column;
  }

  body > div {
width: 100%;
    text-align: center;
  }

  body > div > div {
    background-color: white;
    position: absolute;
  }

  body > div > div > div > p {
    font-size: 40pt;
  }

  #n-100:target,
  #n-99:target,
  #n-98:target,
  #n-97:target,
  #n-96:target,

...


  #n97:target,
  #n98:target,
  #n99:target,
  #n100:target,
  doesnothing
  { display: flex }
  </style>
</head>
<body>
<div>
  <div class="alternate">
    <div>
      <p>0</p>
      <div>
        <a href="#n-1">-1</a>
        <a href="#n1">+1</a>
      </div>
    </div>
  </div>
  <div class="main">
      <div id="n-100">
      <p>-100</p>
      <div>
        <a href="#n-100">END</a>
        <a href="#n-99">+1</a>
      </div>
    </div>
      <div id="n-99">
      <p>-99</p>
      <div>
        <a href="#n-100">-1</a>
        <a href="#n-98">+1</a>
      </div>
    </div>
      <div id="n-98">
      <p>-98</p>
      <div>
        <a href="#n-99">-1</a>
        <a href="#n-97">+1</a>
      </div>
    </div>
      <div id="n-97">
      <p>-97</p>
      <div>
        <a href="#n-98">-1</a>
        <a href="#n-96">+1</a>
      </div>
    </div>
   
    ......
   
   
   
      <div id="n97">
      <p>97</p>
      <div>
        <a href="#n96">-1</a>
        <a href="#n98">+1</a>
      </div>
    </div>
      <div id="n98">
      <p>98</p>
      <div>
        <a href="#n97">-1</a>
        <a href="#n99">+1</a>
      </div>
    </div>
      <div id="n99">
      <p>99</p>
      <div>
        <a href="#n98">-1</a>
        <a href="#n100">+1</a>
      </div>
    </div>
      <div id="n100">
      <p>100</p>
      <div>
        <a href="#n99">-1</a>
        <a href="#n100">END</a>
      </div>
    </div>
    </div>
</div>
</body>
</html

Is this the best solution ? Nope it's not. There is another solution. I will reserved for what I reveal PART 3, because that's where the fun is.

:)
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,547
Reaction score
1,300
Still no solution for PART 3 ?
No worries. Here is the demo for PART 3.
Just the demo, not the actual approach. But it might give you some hints
https://aqua-camila-61.tiiny.site/
:)
No takers ? Well what a pity.

I must say the code is not at my best. Naming convention and definitely can be further streamlined with a different data representation.
However I didn't bother because it's just a demonstration of working with constraints and how to take advantage even when your hands are tied.
PHP:
<?php

define("NOUGHT", 1);
define("CROSS", 2);

function isDone(&$step, $stepkey) {

  global $wonmap;

  for ($i = 0; $i < 3; $i++) {
    // -
    if ($step[0][$i]['player'] == $step[1][$i]['player'] &&
        $step[0][$i]['player'] == $step[2][$i]['player'] &&
        $step[0][$i]['player'] > 0) {
      $wonmap[$stepkey] = "-$i";
      return $step[0][$i]['player'];
    }
    // |
    if ($step[$i][0]['player'] == $step[$i][1]['player'] &&
        $step[$i][0]['player'] == $step[$i][2]['player'] &&
        $step[$i][0]['player'] > 0) {
      $wonmap[$stepkey] = "|$i";
      return $step[$i][0]['player'];
    }
  }
  // \
  if ($step[0][0]['player'] == $step[1][1]['player'] &&
      $step[0][0]['player'] == $step[2][2]['player'] &&
      $step[0][0]['player'] > 0) {
    $wonmap[$stepkey] = "\\";
    return $step[0][0]['player'];
  }
  // /
  if ($step[2][0]['player'] == $step[1][1]['player'] &&
      $step[2][0]['player'] == $step[0][2]['player'] &&
      $step[2][0]['player'] > 0) {
    $wonmap[$stepkey] = "/";
    return $step[2][0]['player'];
  }

  return 0;
}

function genkey($step) {
  $str = "";
  for ($y = 0; $y < 3; $y++) {
    for ($x = 0; $x < 3; $x++) {
      //$str .= $step[$x][$y]['player'].$step[$x][$y]['stepkey'];
      $str .= $step[$x][$y]['player'];
    }
  }
  return md5($str);
}

function create_step(...$cell) {
  return array(
    array($cell[0], $cell[1], $cell[2]),
    array($cell[3], $cell[4], $cell[5]),
    array($cell[6], $cell[7], $cell[8])
  );
}

function create_steps(&$map, $currstepkey, $player, $level) {
  $currstep = &$map[$currstepkey];
  if (isDone($currstep, $currstepkey)) {
    for ($y = 0; $y < 3; $y++) {
      for ($x = 0; $x < 3; $x++) {
        $currstep[$x][$y]['stepkey'] = $currstepkey;
      }
    }
    return $currstepkey;
  }

  for ($y = 0; $y < 3; $y++) {
    for ($x = 0; $x < 3; $x++) {
      if ($currstep[$x][$y]['player'] > 0) {
        $currstep[$x][$y]['stepkey'] = $currstepkey;
        continue;
      }
      $newstep = create_step(...array_merge(...$currstep));
      $newstep[$x][$y] = array('player' => $player, 'stepkey' => 0);
      $newstepkey = genkey($newstep);
      $currstep[$x][$y]['stepkey'] = $newstepkey;
      $map[$newstepkey] = $newstep;
      create_steps($map, $newstepkey, 3 - $player, $level + 1);
    }
  }
  return $currstepkey;
}

$step0    = create_step(...array_fill(0, 9, array('player' => 0, 'stepkey' => 0)));
$step0key = genkey($step0);
$map      = array($step0key => $step0);
$wonmap   = array();
create_steps($map, $step0key, NOUGHT, 0);

// change long md5 id to short numeric keys
$shortids = array( 0 => 0);
$counter = 0;
foreach ($map as $stepkey => $step) {
  $shortids[$stepkey] = $counter++;
}
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
  body {
    user-select: none
  }

  body > p {
    margin: 0px;
    display: none;
    font-size: 60pt;
    width: fit-content;
  }

  body > p > label {
    box-sizing: border-box;
    border: 1px solid black;
    width: 100px;
    height: 100px;
    display: inline-block;
    text-align: center;
    background-color: yellow;
    line-height: 1.2;
    font-weight: 400;
  }

  body > p:has(> input:checked) {
    display: block;
  }

  body > p > input {
    display: none;
    position: relative;
  }

  body > p > span {
    position: absolute;
    background-color: red;
    height: 30px;
    border-radius: 15px;
    animation-duration: 0.1s;
    transform-origin: top left;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    opacity: 0.5;
  }

  body > p > span.slash {
    transform:  translate(30px, 270px) rotate(-45deg) translate(-15px, -15px);
    animation-name: slash;
  }

  body > p > span.backslash {
    transform:  translate(30px, 30px) rotate(45deg) translate(-15px, -15px);
    animation-name: backslash;
  }

  body > p > span.vert0 {
    transform:  translate(50px, 50px) rotate(90deg) translate(-15px, -15px);
    animation-name: horivert;
  }

  body > p > span.vert1 {
    transform:  translate(150px, 50px) rotate(90deg) translate(-15px, -15px);
    animation-name: horivert;
  }

  body > p > span.vert2 {
    transform:  translate(250px, 50px) rotate(90deg) translate(-15px, -15px);
    animation-name: horivert;
  }

  body > p > span.hori0 {
    transform:  translate(50px, 50px) rotate(0deg) translate(-15px, -15px);
    animation-name: horivert;
  }

  body > p > span.hori1 {
    transform:  translate(50px, 150px) rotate(0deg) translate(-15px, -15px);
    animation-name: horivert;
  }

  body > p > span.hori2 {
    transform:  translate(50px, 250px) rotate(0deg) translate(-15px, -15px);
    animation-name: horivert;
  }

  @keyframes backslash {
    from { width: 0px; }
    to { width: 370px; }
  }

  @keyframes slash {
    from { width: 0px; }
    to { width: 370px; }
  }

  @keyframes horivert {
    from { width: 0px; }
    to { width: 240px; }
  }

  .button {
    box-sizing: border-box;
    width: 300px;
    background-color: #4CAF50; /* Green */
    border: 1px solid black;
    border-top: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 20pt;
  }
  </style>
</head>
<body>
  <!-- <?=sizeof(array_keys($map))?>-->
<?php
$nbsp = html_entity_decode("&#160;");
$circle = html_entity_decode("&#9675;");
$cross = html_entity_decode("&#215;");
foreach($map as $key => $step) {
  $checked = $key == $step0key ? " checked" : "";
?>
  <p><input type=radio name=s id=S<?=dechex($shortids[$key])?><?=$checked?>><?php
  $won      = array_key_exists($key, $wonmap) ? $wonmap[$key] : "";;
  $wonlevel = substr($won, 1, 1);
  switch (substr($won, 0, 1)) {
    case "\\":
      echo "<span class=backslash></span>\n";
      break;
    case "/":
      echo "<span class=slash></span>\n";
      break;
    case "-":
      echo "<span class=hori$wonlevel></span>\n";
      break;
    case "|":
      echo "<span class=vert$wonlevel></span>\n";
      break;
    default:
  }
  for($y = 0; $y < 3; $y++) {
    for($x = 0; $x < 3; $x++) {
      $player = $step[$x][$y]['player'] == 1 ? $circle : ($step[$x][$y]['player'] == 2 ? $cross : $nbsp);
  ?><label for=S<?=dechex($shortids[$step[$x][$y]['stepkey']])?>><?=$player?></label><?php } ?><br/><?php } ?></p>
<?php
}
?>
  <label for=S0 class=button>RESTART GAME</label>
</body>
</html>

:)
 
Important Forum Advisory Note
This forum is moderated by volunteer moderators who will react only to members' feedback on posts. Moderators are not employees or representatives of HWZ Forums. Forum members and moderators are responsible for their own posts. Please refer to our Community Guidelines and Standards and Terms and Conditions for more information.
Top