Location>code7788 >text

Hongmeng NEXT Development Case: Random Number Generation

Popularity:171 ℃/2024-11-20 15:52:51

 

[Introduction]

This project is a simple random number generator application that allows the user to generate the desired list of random numbers by setting the range and number of random numbers and selecting whether to allow duplicate random numbers to be generated. The generated results can be copied to the clipboard by clicking the "Copy" button.

[Environmental Preparation]

- Operating system: Windows 10
- Development Tools: DevEco Studio NEXT Beta1 Build Version: 5.0.3.806
- Target device: Huawei Mate60 Pro
- Development language: ArkTS
- Framework: ArkUI
- API version: API 12

[Key technical points]

1. User interface design

The user interface consists of the following main sections:

- Title Bar: Displays the application name.
- Input box: User can input the start value, end value and number of random numbers to be generated.
- Switch: The user can choose whether the generated random numbers are allowed to repeat or not.
- Generate button: generates a random number when clicked.
- Result Display Area: Displays the generated random numbers and provides a copy function.

2. Random number generation algorithms

Random number generation is the focus of this project. The algorithm is divided into two cases depending on whether the user is allowed to generate duplicate random numbers or not:

2.1 No duplication allowed

When the user chooses not to allow the generation of duplicate random numbers, the program uses a Set to store the generated random numbers, using the characteristics of the Set to automatically remove the weight. The specific steps are as follows:

1) Calculate range: Calculate the user-specified random number range range = endValue - startValue + 1.

2) Generate random numbers: Use a temporary array tempArray to assist in generating non-repeating random numbers. Each time a random index randomIndex is generated, a new random number randomNum is taken from tempArray or calculated and added to Set.

3) Update tempArray: Move the last element of tempArray to a random position to ensure that the next random number generated is still unique.

if (!) {
  if (countValue > range) {
    // Display error message
    ().showAlertDialog({
      title: 'Error message',
      message: `The number of random numbers requested exceeds the total number in the range`,
      confirm: {
        defaultFocus: true,
        value: 'I know.',
        fontColor: ,
        backgroundColor: ,
        action: () => {}
      },
      onWillDismiss: () => {},
      alignment: ,
    });
    return;
  }
  for (let i = 0; i < countValue; i++) {
    let randomIndex = (() * (range - i));
    let randomNum = 0;
    if (tempArray[randomIndex] !== undefined) {
      randomNum = tempArray[randomIndex];
    } else {
      randomNum = startValue + randomIndex;
    }
    (randomNum);
    if (tempArray[range - 1 - i] === undefined) {
      tempArray[range - 1 - i] = startValue + range - 1 - i;
    }
    tempArray[randomIndex] = tempArray[range - 1 - i];
  }
   = ((generatedNumbers));
}

3. Clipboard function

For the convenience of the user, the program provides the function of copying the generated random numbers to the clipboard. The specific implementation is as follows:

private copyToClipboard(text: string): void {
  const pasteboardData = (pasteboard.MIMETYPE_TEXT_PLAIN, text);
  const systemPasteboard = ();
  (pasteboardData);
  ({ message: 'Copied' });
}

[complete code]

// Import the Clipboard Service Module for subsequent implementation of copying functionality
import { pasteboard } from '@';
// Importing services for displaying alert messages
import { promptAction } from '@';

// Use the decorator to define an entry component, which is the main interface of the application.
@Entry
@Component
struct RandomNumberGenerator {
  // Define the base spacing, which is used to set the spacing in the layout.
  @State private baseSpacing: number = 30;
  // Store the generated random number string
  @State private generatedNumbers: string = '';
  // Theme color of the application
  @State private primaryColor: string = '#fea024';
  // Color of the text
  @State private fontColor: string = "#2e2e2e";
  // State variable for whether the input box gets focus or not.
  @State private isFocusStart: boolean = false;
  @State private isFocusEnd: boolean = false;
  @State private isFocusCount: boolean = false;
  // Whether to allow duplicate random numbers to be generated
  @State private isUnique: boolean = true;
  // Starting value for random number generation
  @State private startValue: number = 0;
  // End value for random number generation
  @State private endValue: number = 0;
  // Number of random numbers to generate
  @State private countValue: number = 0;

  // Methods for generating random numbers
  private generateRandomNumbers(): void {
    const startValue = ; // Get the currently set start value
    const endValue = ; // Get the end value of the current setting
    const countValue = ; // Get the number of generation currently set
    const range: number = endValue - startValue + 1; // Calculate the generation range


    // Used to store generated random numbers
    const generatedNumbers = new Set<number>(); // Use Set for automatic de-duplication
    const tempArray: number[] = []; // Temporary array to assist in generating non-repeating random numbers

    // If duplicates are not allowed, use a de-duplication algorithm to generate a random number
    if (!) {
      // If the number of random numbers requested exceeds the total number in the range, an error message is displayed
      if (countValue > range) {
        ().showAlertDialog({
          title: 'Error message',
          message: `The number of random numbers requested exceeds the total number in the range`,
          confirm: {
            defaultFocus: true,
            value: 'I know.',
            fontColor: ,
            backgroundColor: ,
            action: () => {} // Callback after clicking on confirmation
          },
          onWillDismiss: () => {}, // Callback when the dialog is about to close
          alignment: , // Alignment of the dialog box
        });
        return;
      }

      for (let i = 0; i < countValue; i++) {
        let randomIndex = (() * (range - i)); // Select a random index within the remaining range
        let randomNum = 0;
        if (tempArray[randomIndex] !== undefined) { // If the index position already has a value, use that value
          randomNum = tempArray[randomIndex];
        } else {
          randomNum = startValue + randomIndex; // otherwise compute a new random number
        }
        (randomNum); // Added to Set, automatically de-duplicated
        if (tempArray[range - 1 - i] === undefined) { // Update the position of the end element
          tempArray[range - 1 - i] = startValue + range - 1 - i;
        }
        tempArray[randomIndex] = tempArray[range - 1 - i]; // Move the end element to a random position
      }
      // Converts the generated random number into a JSON string.
       = ((generatedNumbers));
    } else {
      // If duplicates are allowed, generate random numbers directly
      for (let i = 0; i < ; i++) {
        let randomNumber =  + (() * ( - ));
        (randomNumber);
      }
      // Converts the generated random number into a JSON string.
       = (tempArray);
    }
  }

  // Method for copying the generated random number to the clipboard
  private copyToClipboard(text: string): void {
    const pasteboardData = (pasteboard.MIMETYPE_TEXT_PLAIN, text); // Create clipboard data
    const systemPasteboard = (); // Get the system clipboard
    (pasteboardData); // Setting Clipboard Data
    // Display a message that the copy was successful
    ({ message: 'Copied' });
  }

  // Ways to build a page layout
  build() {
    Column() {
      // Title bar, displaying the application name
      Text("Random number generation")
        .width('100%') // Set the width to 100%
        .height(54) // Set the height to 54
        .fontSize(18) // Set the font size to 18
        .fontWeight(600) // Set the font thickness to 600
        .backgroundColor() // Set the background color to white
        .textAlign() // Set the text to be center-aligned
        .fontColor(); // Set the text color

      // Random number range setting area
      Column() {
        Row() {
          Text(`Random number range`)
            .fontWeight(600) // Set the font thickness to 600
            .fontSize(18) // Set the font size to 18
            .fontColor(); // Set the text color
        }
        .margin({ top: `${}lpx`, left: `${}lpx` }); // Setting the margins

        // Enter two values in the random number range
        Row() {
          TextInput({ placeholder: 'commencement(>=)' }) // Input box with placeholder display
            .layoutWeight(1) // Set the layout weight to 1
            .type() // Set the input type to numeric
            .placeholderColor( ?  : ) // Set the placeholder color
            .fontColor( ?  : ) // Set the text color
            .borderColor( ?  : ) // Set the border color
            .borderWidth(1) // Set the border width
            .borderRadius(10) // Set the radius of the fillet
            .backgroundColor() // Set the background color
            .showUnderline(false) // Do not show underscores
            .onBlur(() =>  = false) // Handling when the input box loses focus
            .onFocus(() =>  = true) // What to do when the input box gets focus
            .onChange((value: string) =>  = Number(value)); // Handling of input value changes

          // Separator
          Line().width(10) // Set the separator width

          TextInput({ placeholder: 'close(<=)' }) // Input box with placeholder display
            .layoutWeight(1) // Set the layout weight to 1
            .type() // Set the input type to numeric
            .placeholderColor( ?  : ) // Set the placeholder color
            .fontColor( ?  : ) // Set the text color
            .borderColor( ?  : ) // Set the border color
            .borderWidth(1) // Set the border width
            .borderRadius(10) // Set the radius of the fillet
            .backgroundColor() // Set the background color
            .showUnderline(false) // Do not show underscores
            .onBlur(() =>  = false) // Handling when the input box loses focus
            .onFocus(() =>  = true) // What to do when the input box gets focus
            .onChange((value: string) =>  = Number(value)); // Handling of input value changes
        }
        .margin({
          left: `${}lpx`, // Left margin
          right: `${}lpx`, // Right margin
          top: `${}lpx`, // Top margin
        });

        // Enter the number of random numbers to generate
        Text('Generate number of random numbers')
          .fontWeight(600) // Set the font thickness to 600
          .fontSize(18) // Set the font size to 18
          .fontColor() // Set the text color
          .margin({ left: `${}lpx`, top: `${}lpx` }); // Setting the margins

        Row() {
          TextInput({ placeholder: '' }) // Input box with placeholder display
            .layoutWeight(1) // Set the layout weight to 1
            .type() // Set the input type to numeric
            .placeholderColor( ?  : ) // Set the placeholder color
            .fontColor( ?  : ) // Set the text color
            .borderColor( ?  : ) // Set the border color
            .borderWidth(1) // Set the border width
            .borderRadius(10) // Set the radius of the fillet
            .backgroundColor() // Set the background color
            .showUnderline(false) // Do not show underscores
            .onBlur(() =>  = false) // Handling when the input box loses focus
            .onFocus(() =>  = true) // What to do when the input box gets focus
            .onChange((value: string) =>  = Number(value)); // Handling of input value changes
        }
        .margin({
          left: `${}lpx`, // Left margin
          right: `${}lpx`, // Right margin
          top: `${}lpx`, // Top margin
        });

        // Switch to set whether the number is repeatable
        Row() {
          Text('Whether the number is repeatable')
            .fontWeight(400) // Set the font thickness to 400
            .fontSize(16) // Set the font size to 16
            .fontColor() // Set the text color
            .layoutWeight(1); // Set the layout weight to 1

          Toggle({ type: , isOn:  }) // Toggle button
            .width('100lpx') // Set the width
            .height('50lpx') // Set the height
            .borderColor() // Set the border color
            .selectedColor() // Set the color when selected
            .onChange((isOn: boolean) =>  = isOn) // Handling of switching state changes
            .align(); // Set the alignment to right justified
        }
        .margin({
          top: `${}lpx`, // Top margin
        })
        .width('100%') // Set the width to 100%
        .padding({
          left: `${}lpx`, // Left inner margin
          right: `${}lpx`, // Right inner margin
          top: `${ / 3}lpx`, // Upper inner margin
        })
        .hitTestBehavior() // Setting up click test behavior
        .onClick(() =>  = !); // Toggle state on click

        // Generate buttons with random numbers
        Text('Start generating')
          .fontColor() // Set the text color to white
          .backgroundColor() // Set the background color to the theme color
          .height(54) // Set the height to 54
          .textAlign() // Set the text to be center-aligned
          .borderRadius(10) // Set the radius of the fillet
          .fontSize(18) // Set the font size to 18
          .width(`${650 -  * 2}lpx`) // Set the width
          .margin({
            top: `${}lpx`, // Top margin
            left: `${}lpx`, // Left margin
            right: `${}lpx`, // Right margin
            bottom: `${}lpx` // Bottom Margin
          })
          .clickEffect({ level: , scale: 0.8 }) // Setting the click effect
          .onClick(() => ()); // Generate random number on click
      }
      .width('650lpx') // Set the width
      .margin({ top: 20 }) // Set the top margin
      .backgroundColor() // Set the background color to white
      .borderRadius(10) // Set the radius of the fillet
      .alignItems(); // Set the horizontal alignment to be left-aligned

      // Display the generated random number
      Column() {
        Text(`The random number generated is:`)
          .fontWeight(600) // Set the font thickness to 600
          .fontSize(18) // Set the font size to 18
          .fontColor() // Set the text color
          .margin({
            top: `${}lpx`, // Top margin
            left: `${}lpx`, // Left margin
          });

        Text(`${}`) // Display the generated random number
          .width('650lpx') // Set the width
          .fontColor() // Set the text color to the theme color
          .fontSize(18) // Set the font size to 18
          .textAlign() // Set the text to be center-aligned
          .padding({ left: 5, right: 5 }) // Setting the inner margins
          .margin({
            top: `${ / 3}lpx` // Top margin
          });

        // Button to copy the generated random number to the clipboard
        Text('Copy')
          .enabled( ? true : false) // Whether the button is available
          .fontColor() // Set the text color to white
          .backgroundColor() // Set the background color to the theme color
          .height(54) // Set the height to 54
          .textAlign() // Set the text to be center-aligned
          .borderRadius(10) // Set the radius of the fillet
          .fontSize(18) // Set the font size to 18
          .width(`${650 -  * 2}lpx`) // Set the width
          .margin({
            top: `${}lpx`, // Top margin
            left: `${}lpx`, // Left margin
            right: `${}lpx`, // Right margin
            bottom: `${}lpx` // Bottom Margin
          })
          .clickEffect({ level: , scale: 0.8 }) // Setting the click effect
          .onClick(() => ()); // Copy random number on click
      }
      .width('650lpx') // Set the width
      .backgroundColor() // Set the background color to white
      .borderRadius(10) // Set the radius of the fillet
      .margin({ top: `${}lpx` }) // Set the top margin
      .alignItems(); // Set the horizontal alignment to be left-aligned
    }
    .height('100%') // Set the height to 100%
    .width('100%') // Set the width to 100%
    .backgroundColor("#f2f3f5"); // set the background color
  }
}